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)  * probe-event.c : perf-probe definition to probe_events format converter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Written by Masami Hiramatsu <mhiramat@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <inttypes.h>
^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) #include <stdarg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <limits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include "build-id.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include "event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include "namespaces.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include "strlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include "strfilter.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include "dso.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include "color.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include "map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include "maps.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <api/fs/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include "trace-event.h"	/* For __maybe_unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include "probe-event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include "probe-finder.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include "probe-file.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include "session.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include "string2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include "strbuf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include <subcmd/pager.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #ifdef HAVE_DEBUGINFOD_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include <elfutils/debuginfod.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define PERFPROBE_GROUP "probe"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) bool probe_event_dry_run;	/* Dry run flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) struct probe_conf probe_conf = { .magic_num = DEFAULT_PROBE_MAGIC_NUM };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define semantic_error(msg ...) pr_err("Semantic error :" msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) int e_snprintf(char *str, size_t size, const char *format, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	va_start(ap, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	ret = vsnprintf(str, size, format, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	if (ret >= (int)size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 		ret = -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) static struct machine *host_machine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) /* Initialize symbol maps and path of vmlinux/modules */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) int init_probe_symbol_maps(bool user_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	symbol_conf.sort_by_name = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	symbol_conf.allow_aliases = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	ret = symbol__init(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 		pr_debug("Failed to init symbol map.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	if (host_machine || user_only)	/* already initialized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	if (symbol_conf.vmlinux_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 		pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	host_machine = machine__new_host();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	if (!host_machine) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 		pr_debug("machine__new_host() failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 		symbol__exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 		ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 		pr_warning("Failed to init vmlinux path.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) void exit_probe_symbol_maps(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	machine__delete(host_machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	host_machine = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	symbol__exit();
^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) static struct ref_reloc_sym *kernel_get_ref_reloc_sym(struct map **pmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	/* kmap->ref_reloc_sym should be set if host_machine is initialized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	struct kmap *kmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	struct map *map = machine__kernel_map(host_machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	if (map__load(map) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	kmap = map__kmap(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	if (!kmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	if (pmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		*pmap = map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	return kmap->ref_reloc_sym;
^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) static int kernel_get_symbol_address_by_name(const char *name, u64 *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 					     bool reloc, bool reladdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	struct ref_reloc_sym *reloc_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	/* ref_reloc_sym is just a label. Need a special fix*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	reloc_sym = kernel_get_ref_reloc_sym(&map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	if (reloc_sym && strcmp(name, reloc_sym->name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 		*addr = (!map->reloc || reloc) ? reloc_sym->addr :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 			reloc_sym->unrelocated_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 		sym = machine__find_kernel_symbol_by_name(host_machine, name, &map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		if (!sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 		*addr = map->unmap_ip(map, sym->start) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 			((reloc) ? 0 : map->reloc) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 			((reladdr) ? map->start : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) static struct map *kernel_get_module_map(const char *module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	struct maps *maps = machine__kernel_maps(host_machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	struct map *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	/* A file path -- this is an offline module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	if (module && strchr(module, '/'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 		return dso__new_map(module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	if (!module) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		pos = machine__kernel_map(host_machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		return map__get(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	maps__for_each_entry(maps, pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 		/* short_name is "[module]" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		if (strncmp(pos->dso->short_name + 1, module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 			    pos->dso->short_name_len - 2) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 		    module[pos->dso->short_name_len - 2] == '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 			return map__get(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) struct map *get_target_map(const char *target, struct nsinfo *nsi, bool user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	/* Init maps of given executable or kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	if (user) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 		struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		map = dso__new_map(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		if (map && map->dso) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 			nsinfo__put(map->dso->nsinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 			map->dso->nsinfo = nsinfo__get(nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 		return map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 		return kernel_get_module_map(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) static int convert_exec_to_group(const char *exec, char **result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	char *ptr1, *ptr2, *exec_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	char buf[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	exec_copy = strdup(exec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	if (!exec_copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	ptr1 = basename(exec_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	if (!ptr1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	for (ptr2 = ptr1; *ptr2 != '\0'; ptr2++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		if (!isalnum(*ptr2) && *ptr2 != '_') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 			*ptr2 = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	ret = e_snprintf(buf, 64, "%s_%s", PERFPROBE_GROUP, ptr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	*result = strdup(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	ret = *result ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	free(exec_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) static void clear_perf_probe_point(struct perf_probe_point *pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	zfree(&pp->file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	zfree(&pp->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	zfree(&pp->lazy_line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	for (i = 0; i < ntevs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		clear_probe_trace_event(tevs + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) static bool kprobe_blacklist__listed(unsigned long address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) static bool kprobe_warn_out_range(const char *symbol, unsigned long address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	map = kernel_get_module_map(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	if (map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		ret = address <= map->start || map->end < address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 			pr_warning("%s is out of .text, skip it.\n", symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		map__put(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	if (!ret && kprobe_blacklist__listed(address)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		pr_warning("%s is blacklisted function, skip it.\n", symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 		ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265)  * @module can be module name of module file path. In case of path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266)  * inspect elf and find out what is actual module name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267)  * Caller has to free mod_name after using it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) static char *find_module_name(const char *module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	Elf *elf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	GElf_Ehdr ehdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	GElf_Shdr shdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	Elf_Data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	Elf_Scn *sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	char *mod_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	int name_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	fd = open(module, O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	if (elf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 		goto elf_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	if (gelf_getehdr(elf, &ehdr) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 		goto ret_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	sec = elf_section_by_name(elf, &ehdr, &shdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 			".gnu.linkonce.this_module", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	if (!sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		goto ret_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	data = elf_getdata(sec, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	if (!data || !data->d_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		goto ret_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	 * NOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	 * '.gnu.linkonce.this_module' section of kernel module elf directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	 * maps to 'struct module' from linux/module.h. This section contains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	 * actual module name which will be used by kernel after loading it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	 * But, we cannot use 'struct module' here since linux/module.h is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	 * exposed to user-space. Offset of 'name' has remained same from long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	 * time, so hardcoding it here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		name_offset = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	else	/* expect ELFCLASS64 by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		name_offset = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	mod_name = strdup((char *)data->d_buf + name_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) ret_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	elf_end(elf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) elf_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	return mod_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) #ifdef HAVE_DWARF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) static int kernel_get_module_dso(const char *module, struct dso **pdso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	struct dso *dso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	const char *vmlinux_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	if (module) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 		char module_name[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		snprintf(module_name, sizeof(module_name), "[%s]", module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		map = maps__find_by_name(&host_machine->kmaps, module_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		if (map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 			dso = map->dso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 			goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 		pr_debug("Failed to find module %s.\n", module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	map = machine__kernel_map(host_machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	dso = map->dso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	if (!dso->has_build_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		dso__read_running_kernel_build_id(dso, host_machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	vmlinux_name = symbol_conf.vmlinux_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	dso->load_errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	if (vmlinux_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		ret = dso__load_vmlinux(dso, map, vmlinux_name, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 		ret = dso__load_vmlinux_path(dso, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	*pdso = dso;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362)  * Some binaries like glibc have special symbols which are on the symbol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363)  * table, but not in the debuginfo. If we can find the address of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364)  * symbol from map, we can translate the address back to the probe point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) static int find_alternative_probe_point(struct debuginfo *dinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 					struct perf_probe_point *pp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 					struct perf_probe_point *result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 					const char *target, struct nsinfo *nsi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 					bool uprobes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	struct map *map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	u64 address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	/* This can work only for function-name based one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	if (!pp->function || pp->file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		return -ENOTSUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	map = get_target_map(target, nsi, uprobes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	if (!map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	/* Find the address of given function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	map__for_each_symbol_by_name(map, pp->function, sym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		if (uprobes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 			address = sym->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 			if (sym->type == STT_GNU_IFUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 				pr_warning("Warning: The probe function (%s) is a GNU indirect function.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 					   "Consider identifying the final function used at run time and set the probe directly on that.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 					   pp->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 			address = map->unmap_ip(map, sym->start) - map->reloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	if (!address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	pr_debug("Symbol %s address found : %" PRIx64 "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 			pp->function, address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	ret = debuginfo__find_probe_point(dinfo, (unsigned long)address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 					  result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	if (ret <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		ret = (!ret) ? -ENOENT : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		result->offset += pp->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		result->line += pp->line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		result->retprobe = pp->retprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	map__put(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	return ret;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) static int get_alternative_probe_event(struct debuginfo *dinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 				       struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 				       struct perf_probe_point *tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	memcpy(tmp, &pev->point, sizeof(*tmp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	memset(&pev->point, 0, sizeof(pev->point));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	ret = find_alternative_probe_point(dinfo, tmp, &pev->point, pev->target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 					   pev->nsi, pev->uprobes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 		memcpy(&pev->point, tmp, sizeof(*tmp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) static int get_alternative_line_range(struct debuginfo *dinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 				      struct line_range *lr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 				      const char *target, bool user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	struct perf_probe_point pp = { .function = lr->function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 				       .file = lr->file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 				       .line = lr->start };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	struct perf_probe_point result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	int ret, len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	memset(&result, 0, sizeof(result));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	if (lr->end != INT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		len = lr->end - lr->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	ret = find_alternative_probe_point(dinfo, &pp, &result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 					   target, NULL, user);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		lr->function = result.function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		lr->file = result.file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		lr->start = result.line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		if (lr->end != INT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 			lr->end = lr->start + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		clear_perf_probe_point(&pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) #ifdef HAVE_DEBUGINFOD_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) static struct debuginfo *open_from_debuginfod(struct dso *dso, struct nsinfo *nsi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 					      bool silent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	debuginfod_client *c = debuginfod_begin();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	char sbuild_id[SBUILD_ID_SIZE + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	struct debuginfo *ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	struct nscookie nsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	char *path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	if (!c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	build_id__sprintf(&dso->bid, sbuild_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	fd = debuginfod_find_debuginfo(c, (const unsigned char *)sbuild_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 					0, &path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	if (fd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	debuginfod_end(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	if (fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		if (!silent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 			pr_debug("Failed to find debuginfo in debuginfod.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	if (!silent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 		pr_debug("Load debuginfo from debuginfod (%s)\n", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	nsinfo__mountns_enter(nsi, &nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	ret = debuginfo__new((const char *)path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	nsinfo__mountns_exit(&nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) struct debuginfo *open_from_debuginfod(struct dso *dso __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 				       struct nsinfo *nsi __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 				       bool silent __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) /* Open new debuginfo of given module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) static struct debuginfo *open_debuginfo(const char *module, struct nsinfo *nsi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 					bool silent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	const char *path = module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	char reason[STRERR_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	struct debuginfo *ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	struct dso *dso = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	struct nscookie nsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	if (!module || !strchr(module, '/')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		err = kernel_get_module_dso(module, &dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 			if (!dso || dso->load_errno == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 				if (!str_error_r(-err, reason, STRERR_BUFSIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 					strcpy(reason, "(unknown)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 				dso__strerror_load(dso, reason, STRERR_BUFSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 			if (dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 				ret = open_from_debuginfod(dso, nsi, silent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 			if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 			if (!silent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 				if (module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 					pr_err("Module %s is not loaded, please specify its full path name.\n", module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 					pr_err("Failed to find the path for the kernel: %s\n", reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 		path = dso->long_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	nsinfo__mountns_enter(nsi, &nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	ret = debuginfo__new(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	if (!ret && !silent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		pr_warning("The %s file has no debug information.\n", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		if (!module || !strtailcmp(path, ".ko"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 			pr_warning("Rebuild with CONFIG_DEBUG_INFO=y, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 			pr_warning("Rebuild with -g, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 		pr_warning("or install an appropriate debuginfo package.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	nsinfo__mountns_exit(&nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) /* For caching the last debuginfo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) static struct debuginfo *debuginfo_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) static char *debuginfo_cache_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) static struct debuginfo *debuginfo_cache__open(const char *module, bool silent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	const char *path = module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	/* If the module is NULL, it should be the kernel. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	if (!module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		path = "kernel";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	if (debuginfo_cache_path && !strcmp(debuginfo_cache_path, path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	/* Copy module path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	free(debuginfo_cache_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	debuginfo_cache_path = strdup(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	if (!debuginfo_cache_path) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		debuginfo__delete(debuginfo_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		debuginfo_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	debuginfo_cache = open_debuginfo(module, NULL, silent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	if (!debuginfo_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		zfree(&debuginfo_cache_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	return debuginfo_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) static void debuginfo_cache__exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	debuginfo__delete(debuginfo_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	debuginfo_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	zfree(&debuginfo_cache_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) static int get_text_start_address(const char *exec, unsigned long *address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 				  struct nsinfo *nsi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	Elf *elf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	GElf_Ehdr ehdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	GElf_Shdr shdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	int fd, ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	struct nscookie nsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	nsinfo__mountns_enter(nsi, &nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	fd = open(exec, O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	nsinfo__mountns_exit(&nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	if (elf == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		goto out_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	if (gelf_getehdr(elf, &ehdr) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	if (!elf_section_by_name(elf, &ehdr, &shdr, ".text", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	*address = shdr.sh_addr - shdr.sh_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	elf_end(elf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) out_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631)  * Convert trace point to probe point with debuginfo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 					    struct perf_probe_point *pp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 					    bool is_kprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	struct debuginfo *dinfo = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	unsigned long stext = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	u64 addr = tp->address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	/* convert the address to dwarf address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	if (!is_kprobe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		if (!addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		ret = get_text_start_address(tp->module, &stext, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		addr += stext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	} else if (tp->symbol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		/* If the module is given, this returns relative address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		ret = kernel_get_symbol_address_by_name(tp->symbol, &addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 							false, !!tp->module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		addr += tp->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	pr_debug("try to find information at %" PRIx64 " in %s\n", addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		 tp->module ? : "kernel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	dinfo = debuginfo_cache__open(tp->module, verbose <= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	if (dinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		ret = debuginfo__find_probe_point(dinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 						 (unsigned long)addr, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		pp->retprobe = tp->retprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	pr_debug("Failed to find corresponding probes from debuginfo.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	return ret ? : -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) /* Adjust symbol name and address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) static int post_process_probe_trace_point(struct probe_trace_point *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 					   struct map *map, unsigned long offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	u64 addr = tp->address - offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	sym = map__find_symbol(map, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	if (!sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	if (strcmp(sym->name, tp->symbol)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		/* If we have no realname, use symbol for it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		if (!tp->realname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 			tp->realname = tp->symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 			free(tp->symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		tp->symbol = strdup(sym->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		if (!tp->symbol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	tp->offset = addr - sym->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	tp->address -= offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708)  * Rename DWARF symbols to ELF symbols -- gcc sometimes optimizes functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709)  * and generate new symbols with suffixes such as .constprop.N or .isra.N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710)  * etc. Since those symbols are not recorded in DWARF, we have to find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711)  * correct generated symbols from offline ELF binary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712)  * For online kernel or uprobes we don't need this because those are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713)  * rebased on _text, or already a section relative address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) post_process_offline_probe_trace_events(struct probe_trace_event *tevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 					int ntevs, const char *pathname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	unsigned long stext = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	/* Prepare a map for offline binary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	map = dso__new_map(pathname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	if (!map || get_text_start_address(pathname, &stext, NULL) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		pr_warning("Failed to get ELF symbols for %s\n", pathname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	for (i = 0; i < ntevs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		ret = post_process_probe_trace_point(&tevs[i].point,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 						     map, stext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	map__put(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 					  int ntevs, const char *exec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 					  struct nsinfo *nsi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	unsigned long stext = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	if (!exec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	ret = get_text_start_address(exec, &stext, nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	for (i = 0; i < ntevs && ret >= 0; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		/* point.address is the address of point.symbol + point.offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		tevs[i].point.address -= stext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		tevs[i].point.module = strdup(exec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		if (!tevs[i].point.module) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		tevs[i].uprobes = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) post_process_module_probe_trace_events(struct probe_trace_event *tevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 				       int ntevs, const char *module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 				       struct debuginfo *dinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	Dwarf_Addr text_offs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	char *mod_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	if (!module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	map = get_target_map(module, NULL, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	if (!map || debuginfo__get_text_offset(dinfo, &text_offs, true) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		pr_warning("Failed to get ELF symbols for %s\n", module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	mod_name = find_module_name(module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	for (i = 0; i < ntevs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		ret = post_process_probe_trace_point(&tevs[i].point,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 						map, (unsigned long)text_offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		tevs[i].point.module =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 			strdup(mod_name ? mod_name : module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		if (!tevs[i].point.module) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	free(mod_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	map__put(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) post_process_kernel_probe_trace_events(struct probe_trace_event *tevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 				       int ntevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	struct ref_reloc_sym *reloc_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	char *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	int i, skipped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	/* Skip post process if the target is an offline kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	if (symbol_conf.ignore_vmlinux_buildid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		return post_process_offline_probe_trace_events(tevs, ntevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 						symbol_conf.vmlinux_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	reloc_sym = kernel_get_ref_reloc_sym(&map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	if (!reloc_sym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		pr_warning("Relocated base symbol is not found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	for (i = 0; i < ntevs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		if (!tevs[i].point.address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		if (tevs[i].point.retprobe && !kretprobe_offset_is_supported())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		 * If we found a wrong one, mark it by NULL symbol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		 * Since addresses in debuginfo is same as objdump, we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		 * to convert it to addresses on memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		if (kprobe_warn_out_range(tevs[i].point.symbol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 			map__objdump_2mem(map, tevs[i].point.address))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 			tmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 			skipped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 			tmp = strdup(reloc_sym->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 			if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 				return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		/* If we have no realname, use symbol for it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		if (!tevs[i].point.realname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 			tevs[i].point.realname = tevs[i].point.symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 			free(tevs[i].point.symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		tevs[i].point.symbol = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		tevs[i].point.offset = tevs[i].point.address -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 			(map->reloc ? reloc_sym->unrelocated_addr :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 				      reloc_sym->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	return skipped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) void __weak
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) arch__post_process_probe_trace_events(struct perf_probe_event *pev __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 				      int ntevs __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) /* Post processing the probe events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) static int post_process_probe_trace_events(struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 					   struct probe_trace_event *tevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 					   int ntevs, const char *module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 					   bool uprobe, struct debuginfo *dinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	if (uprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		ret = add_exec_to_probe_trace_events(tevs, ntevs, module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 						     pev->nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	else if (module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		/* Currently ref_reloc_sym based probe is not for drivers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		ret = post_process_module_probe_trace_events(tevs, ntevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 							     module, dinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		ret = post_process_kernel_probe_trace_events(tevs, ntevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		arch__post_process_probe_trace_events(pev, ntevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) /* Try to find perf_probe_event with debuginfo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 					  struct probe_trace_event **tevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	bool need_dwarf = perf_probe_event_need_dwarf(pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	struct perf_probe_point tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	struct debuginfo *dinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	int ntevs, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	dinfo = open_debuginfo(pev->target, pev->nsi, !need_dwarf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	if (!dinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		if (need_dwarf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		pr_debug("Could not open debuginfo. Try to use symbols.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	pr_debug("Try to find probe point from debuginfo.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	/* Searching trace events corresponding to a probe event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	ntevs = debuginfo__find_trace_events(dinfo, pev, tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	if (ntevs == 0)	{  /* Not found, retry with an alternative */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		ret = get_alternative_probe_event(dinfo, pev, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 			ntevs = debuginfo__find_trace_events(dinfo, pev, tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 			 * Write back to the original probe_event for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 			 * setting appropriate (user given) event name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 			clear_perf_probe_point(&pev->point);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 			memcpy(&pev->point, &tmp, sizeof(tmp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	if (ntevs > 0) {	/* Succeeded to find trace events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		pr_debug("Found %d probe_trace_events.\n", ntevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		ret = post_process_probe_trace_events(pev, *tevs, ntevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 					pev->target, pev->uprobes, dinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		if (ret < 0 || ret == ntevs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 			pr_debug("Post processing failed or all events are skipped. (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 			clear_probe_trace_events(*tevs, ntevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 			zfree(tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 			ntevs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	debuginfo__delete(dinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	if (ntevs == 0)	{	/* No error but failed to find probe point. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		pr_warning("Probe point '%s' not found.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 			   synthesize_perf_probe_point(&pev->point));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	} else if (ntevs < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		/* Error path : ntevs < 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		if (ntevs == -EBADF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 			pr_warning("Warning: No dwarf info found in the vmlinux - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 				"please rebuild kernel with CONFIG_DEBUG_INFO=y.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		if (!need_dwarf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 			pr_debug("Trying to use symbols.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	return ntevs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) #define LINEBUF_SIZE 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) #define NR_ADDITIONAL_LINES 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) static int __show_one_line(FILE *fp, int l, bool skip, bool show_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	char buf[LINEBUF_SIZE], sbuf[STRERR_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	const char *color = show_num ? "" : PERF_COLOR_BLUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	const char *prefix = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		if (skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		if (!prefix) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 			prefix = show_num ? "%7d  " : "         ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 			color_fprintf(stdout, color, prefix, l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		color_fprintf(stdout, color, "%s", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	} while (strchr(buf, '\n') == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	if (ferror(fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		pr_warning("File read error: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 			   str_error_r(errno, sbuf, sizeof(sbuf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) static int _show_one_line(FILE *fp, int l, bool skip, bool show_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	int rv = __show_one_line(fp, l, skip, show_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	if (rv == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		pr_warning("Source file is shorter than expected.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		rv = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) #define show_one_line_with_num(f,l)	_show_one_line(f,l,false,true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) #define show_one_line(f,l)		_show_one_line(f,l,false,false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) #define skip_one_line(f,l)		_show_one_line(f,l,true,false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) #define show_one_line_or_eof(f,l)	__show_one_line(f,l,false,false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)  * Show line-range always requires debuginfo to find source file and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)  * line number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static int __show_line_range(struct line_range *lr, const char *module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 			     bool user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	struct build_id bid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	int l = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	struct int_node *ln;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	struct debuginfo *dinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	char *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	char sbuf[STRERR_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	char sbuild_id[SBUILD_ID_SIZE] = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	/* Search a line range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	dinfo = open_debuginfo(module, NULL, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	if (!dinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	ret = debuginfo__find_line_range(dinfo, lr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	if (!ret) {	/* Not found, retry with an alternative */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		ret = get_alternative_line_range(dinfo, lr, module, user);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 			ret = debuginfo__find_line_range(dinfo, lr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	if (dinfo->build_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		build_id__init(&bid, dinfo->build_id, BUILD_ID_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		build_id__sprintf(&bid, sbuild_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	debuginfo__delete(dinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	if (ret == 0 || ret == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		pr_warning("Specified source line is not found.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	} else if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		pr_warning("Debuginfo analysis failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	/* Convert source file path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	tmp = lr->path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	ret = find_source_path(tmp, sbuild_id, lr->comp_dir, &lr->path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	/* Free old path when new path is assigned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	if (tmp != lr->path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		free(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		pr_warning("Failed to find source file path.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	setup_pager();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	if (lr->function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		fprintf(stdout, "<%s@%s:%d>\n", lr->function, lr->path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 			lr->start - lr->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		fprintf(stdout, "<%s:%d>\n", lr->path, lr->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	fp = fopen(lr->path, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	if (fp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		pr_warning("Failed to open %s: %s\n", lr->path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 			   str_error_r(errno, sbuf, sizeof(sbuf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	/* Skip to starting line number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	while (l < lr->start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		ret = skip_one_line(fp, l++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 			goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	intlist__for_each_entry(ln, lr->line_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		for (; ln->i > l; l++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 			ret = show_one_line(fp, l - lr->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 				goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		ret = show_one_line_with_num(fp, l++ - lr->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 			goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	if (lr->end == INT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		lr->end = l + NR_ADDITIONAL_LINES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	while (l <= lr->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		ret = show_one_line_or_eof(fp, l++ - lr->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		if (ret <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) int show_line_range(struct line_range *lr, const char *module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		    struct nsinfo *nsi, bool user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	struct nscookie nsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	ret = init_probe_symbol_maps(user);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	nsinfo__mountns_enter(nsi, &nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	ret = __show_line_range(lr, module, user);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	nsinfo__mountns_exit(&nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	exit_probe_symbol_maps();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) static int show_available_vars_at(struct debuginfo *dinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 				  struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 				  struct strfilter *_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	int ret, i, nvars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	struct str_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	struct variable_list *vls = NULL, *vl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	struct perf_probe_point tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	const char *var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	buf = synthesize_perf_probe_point(&pev->point);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	pr_debug("Searching variables at %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	ret = debuginfo__find_available_vars_at(dinfo, pev, &vls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	if (!ret) {  /* Not found, retry with an alternative */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 		ret = get_alternative_probe_event(dinfo, pev, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 		if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 			ret = debuginfo__find_available_vars_at(dinfo, pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 								&vls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 			/* Release the old probe_point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 			clear_perf_probe_point(&tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	if (ret <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		if (ret == 0 || ret == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 			pr_err("Failed to find the address of %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 			ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 			pr_warning("Debuginfo analysis failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	/* Some variables are found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	fprintf(stdout, "Available variables at %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	for (i = 0; i < ret; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		vl = &vls[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		 * A probe point might be converted to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 		 * several trace points.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 			vl->point.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		zfree(&vl->point.symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		nvars = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		if (vl->vars) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 			strlist__for_each_entry(node, vl->vars) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 				var = strchr(node->s, '\t') + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 				if (strfilter__compare(_filter, var)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 					fprintf(stdout, "\t\t%s\n", node->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 					nvars++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 			strlist__delete(vl->vars);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		if (nvars == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 			fprintf(stdout, "\t\t(No matched variables)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	free(vls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) /* Show available variables on given probe point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) int show_available_vars(struct perf_probe_event *pevs, int npevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 			struct strfilter *_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	struct debuginfo *dinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	ret = init_probe_symbol_maps(pevs->uprobes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	dinfo = open_debuginfo(pevs->target, pevs->nsi, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	if (!dinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 		ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	setup_pager();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	for (i = 0; i < npevs && ret >= 0; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		ret = show_available_vars_at(dinfo, &pevs[i], _filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	debuginfo__delete(dinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	exit_probe_symbol_maps();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) #else	/* !HAVE_DWARF_SUPPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) static void debuginfo_cache__exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) find_perf_probe_point_from_dwarf(struct probe_trace_point *tp __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 				 struct perf_probe_point *pp __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 				 bool is_kprobe __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 				struct probe_trace_event **tevs __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	if (perf_probe_event_need_dwarf(pev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 		pr_warning("Debuginfo-analysis is not supported.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 		return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) int show_line_range(struct line_range *lr __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 		    const char *module __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		    struct nsinfo *nsi __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		    bool user __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	pr_warning("Debuginfo-analysis is not supported.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) int show_available_vars(struct perf_probe_event *pevs __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 			int npevs __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 			struct strfilter *filter __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	pr_warning("Debuginfo-analysis is not supported.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) void line_range__clear(struct line_range *lr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	zfree(&lr->function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	zfree(&lr->file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	zfree(&lr->path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	zfree(&lr->comp_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	intlist__delete(lr->line_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) int line_range__init(struct line_range *lr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	memset(lr, 0, sizeof(*lr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	lr->line_list = intlist__new(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	if (!lr->line_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) static int parse_line_num(char **ptr, int *val, const char *what)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	const char *start = *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	*val = strtol(*ptr, ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	if (errno || *ptr == start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 		semantic_error("'%s' is not a valid number.\n", what);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) /* Check the name is good for event, group or function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) static bool is_c_func_name(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	if (!isalpha(*name) && *name != '_')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	while (*++name != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)  * Stuff 'lr' according to the line range described by 'arg'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)  * The line range syntax is described by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)  *         SRC[:SLN[+NUM|-ELN]]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)  *         FNC[@SRC][:SLN[+NUM|-ELN]]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) int parse_line_range_desc(const char *arg, struct line_range *lr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	char *range, *file, *name = strdup(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	lr->start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	lr->end = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	range = strchr(name, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	if (range) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 		*range++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 		err = parse_line_num(&range, &lr->start, "start line");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 		if (*range == '+' || *range == '-') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 			const char c = *range++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 			err = parse_line_num(&range, &lr->end, "end line");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 				goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 			if (c == '+') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 				lr->end += lr->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 				 * Adjust the number of lines here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 				 * If the number of lines == 1, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 				 * the end of line should be equal to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 				 * the start of line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 				lr->end--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 		pr_debug("Line range is %d to %d\n", lr->start, lr->end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 		if (lr->start > lr->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 			semantic_error("Start line must be smaller"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 				       " than end line.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 		if (*range != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 			semantic_error("Tailing with invalid str '%s'.\n", range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	file = strchr(name, '@');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	if (file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 		*file = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		lr->file = strdup(++file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		if (lr->file == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		lr->function = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	} else if (strchr(name, '/') || strchr(name, '.'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 		lr->file = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	else if (is_c_func_name(name))/* We reuse it for checking funcname */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 		lr->function = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	else {	/* Invalid name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 		semantic_error("'%s' is not a valid function name.\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	free(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	ptr = strpbrk_esc(*arg, ":");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	if (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		*ptr = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 		if (!pev->sdt && !is_c_func_name(*arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 			goto ng_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 		pev->group = strdup_esc(*arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 		if (!pev->group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 		*arg = ptr + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 		pev->group = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	pev->event = strdup_esc(*arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	if (pev->event == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	if (!pev->sdt && !is_c_func_name(pev->event)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 		zfree(&pev->event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) ng_name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 		zfree(&pev->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 		semantic_error("%s is bad for event name -it must "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 			       "follow C symbol-naming rule.\n", *arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) /* Parse probepoint definition. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	struct perf_probe_point *pp = &pev->point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	char *ptr, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	char c, nc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	bool file_spec = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	 * <Syntax>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	 * perf probe [GRP:][EVENT=]SRC[:LN|;PTN]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	 * perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	 * perf probe %[GRP:]SDT_EVENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	if (!arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	if (is_sdt_event(arg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 		pev->sdt = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 		if (arg[0] == '%')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 			arg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	ptr = strpbrk_esc(arg, ";=@+%");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	if (pev->sdt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 		if (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 			if (*ptr != '@') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 				semantic_error("%s must be an SDT name.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 					       arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 			/* This must be a target file name or build id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 			tmp = build_id_cache__complement(ptr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 			if (tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 				pev->target = build_id_cache__origname(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 				free(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 				pev->target = strdup_esc(ptr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 			if (!pev->target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 				return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 			*ptr = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 		ret = parse_perf_probe_event_name(&arg, pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 		if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 			if (asprintf(&pev->point.function, "%%%s", pev->event) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 				ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	if (ptr && *ptr == '=') {	/* Event name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 		*ptr = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 		tmp = ptr + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 		ret = parse_perf_probe_event_name(&arg, pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		arg = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	 * Check arg is function or file name and copy it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	 * We consider arg to be a file spec if and only if it satisfies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	 * all of the below criteria::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	 * - it does not include any of "+@%",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	 * - it includes one of ":;", and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	 * - it has a period '.' in the name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	 * Otherwise, we consider arg to be a function specification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	if (!strpbrk_esc(arg, "+@%")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 		ptr = strpbrk_esc(arg, ";:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 		/* This is a file spec if it includes a '.' before ; or : */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 		if (ptr && memchr(arg, '.', ptr - arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 			file_spec = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	ptr = strpbrk_esc(arg, ";:+@%");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	if (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 		nc = *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 		*ptr++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	if (arg[0] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 		tmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 		tmp = strdup_esc(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 		if (tmp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	if (file_spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 		pp->file = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 		pp->function = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 		 * Keep pp->function even if this is absolute address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 		 * so it can mark whether abs_address is valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 		 * Which make 'perf probe lib.bin 0x0' possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 		 * Note that checking length of tmp is not needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 		 * because when we access tmp[1] we know tmp[0] is '0',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 		 * so tmp[1] should always valid (but could be '\0').
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 		if (tmp && !strncmp(tmp, "0x", 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 			pp->abs_address = strtoul(pp->function, &tmp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 			if (*tmp != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 				semantic_error("Invalid absolute address.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	/* Parse other options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	while (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 		arg = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 		c = nc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		if (c == ';') {	/* Lazy pattern must be the last part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 			pp->lazy_line = strdup(arg); /* let leave escapes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 			if (pp->lazy_line == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 				return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 		ptr = strpbrk_esc(arg, ";:+@%");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 		if (ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 			nc = *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 			*ptr++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 		switch (c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		case ':':	/* Line number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 			pp->line = strtoul(arg, &tmp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 			if (*tmp != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 				semantic_error("There is non-digit char"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 					       " in line number.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 		case '+':	/* Byte offset from a symbol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 			pp->offset = strtoul(arg, &tmp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 			if (*tmp != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 				semantic_error("There is non-digit character"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 						" in offset.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 		case '@':	/* File name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 			if (pp->file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 				semantic_error("SRC@SRC is not allowed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 			pp->file = strdup_esc(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 			if (pp->file == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 				return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 		case '%':	/* Probe places */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 			if (strcmp(arg, "return") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 				pp->retprobe = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 			} else {	/* Others not supported yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 				semantic_error("%%%s is not supported.\n", arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 				return -ENOTSUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 		default:	/* Buggy case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 			pr_err("This program has a bug at %s:%d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 				__FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 			return -ENOTSUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 	/* Exclusion check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	if (pp->lazy_line && pp->line) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 		semantic_error("Lazy pattern can't be used with"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 			       " line number.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	if (pp->lazy_line && pp->offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 		semantic_error("Lazy pattern can't be used with offset.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	if (pp->line && pp->offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 		semantic_error("Offset can't be used with line number.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	if (!pp->line && !pp->lazy_line && pp->file && !pp->function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 		semantic_error("File always requires line number or "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 			       "lazy pattern.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	if (pp->offset && !pp->function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 		semantic_error("Offset requires an entry function.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 		semantic_error("Offset/Line/Lazy pattern can't be used with "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 			       "return probe.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 		 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 		 pp->lazy_line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) /* Parse perf-probe event argument */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 	char *tmp, *goodname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	struct perf_probe_arg_field **fieldp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	pr_debug("parsing arg: %s into ", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	tmp = strchr(str, '=');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	if (tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 		arg->name = strndup(str, tmp - str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 		if (arg->name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 		pr_debug("name:%s ", arg->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 		str = tmp + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	tmp = strchr(str, '@');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 	if (tmp && tmp != str && !strcmp(tmp + 1, "user")) { /* user attr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 		if (!user_access_is_supported()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 			semantic_error("ftrace does not support user access\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 		*tmp = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 		arg->user_access = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 		pr_debug("user_access ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	tmp = strchr(str, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	if (tmp) {	/* Type setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 		*tmp = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 		arg->type = strdup(tmp + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 		if (arg->type == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 		pr_debug("type:%s ", arg->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	tmp = strpbrk(str, "-.[");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	if (!is_c_varname(str) || !tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 		/* A variable, register, symbol or special value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 		arg->var = strdup(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 		if (arg->var == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 		pr_debug("%s\n", arg->var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	/* Structure fields or array element */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	arg->var = strndup(str, tmp - str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	if (arg->var == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	goodname = arg->var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	pr_debug("%s, ", arg->var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	fieldp = &arg->field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 		*fieldp = zalloc(sizeof(struct perf_probe_arg_field));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 		if (*fieldp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 		if (*tmp == '[') {	/* Array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 			str = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 			(*fieldp)->index = strtol(str + 1, &tmp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 			(*fieldp)->ref = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 			if (*tmp != ']' || tmp == str + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 				semantic_error("Array index must be a"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 						" number.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 			tmp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 			if (*tmp == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 				tmp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 		} else {		/* Structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 			if (*tmp == '.') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 				str = tmp + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 				(*fieldp)->ref = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 			} else if (tmp[1] == '>') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 				str = tmp + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 				(*fieldp)->ref = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 				semantic_error("Argument parse error: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 					       str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 			tmp = strpbrk(str, "-.[");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		if (tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 			(*fieldp)->name = strndup(str, tmp - str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 			if ((*fieldp)->name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 				return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 			if (*str != '[')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 				goodname = (*fieldp)->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 			pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 			fieldp = &(*fieldp)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	} while (tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	(*fieldp)->name = strdup(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	if ((*fieldp)->name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	if (*str != '[')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 		goodname = (*fieldp)->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	/* If no name is specified, set the last field name (not array index)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	if (!arg->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 		arg->name = strdup(goodname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 		if (arg->name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) /* Parse perf-probe event command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	char **argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	int argc, i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	argv = argv_split(cmd, &argc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	if (!argv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		pr_debug("Failed to split arguments.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	if (argc - 1 > MAX_PROBE_ARGS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 		semantic_error("Too many probe arguments (%d).\n", argc - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 		ret = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	/* Parse probe point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	ret = parse_perf_probe_point(argv[0], pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	/* Generate event name if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	if (!pev->event && pev->point.function && pev->point.line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 			&& !pev->point.lazy_line && !pev->point.offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 		if (asprintf(&pev->event, "%s_L%d", pev->point.function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 			pev->point.line) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	/* Copy arguments and ensure return probe has no C argument */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	pev->nargs = argc - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	if (pev->args == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	for (i = 0; i < pev->nargs && ret >= 0; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 		ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 		if (ret >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 		    is_c_varname(pev->args[i].var) && pev->point.retprobe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 			semantic_error("You can't specify local variable for"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 				       " kretprobe.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	argv_free(argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) /* Returns true if *any* ARG is either C variable, $params or $vars. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) bool perf_probe_with_var(struct perf_probe_event *pev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 	for (i = 0; i < pev->nargs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 		if (is_c_varname(pev->args[i].var)              ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 		    !strcmp(pev->args[i].var, PROBE_ARG_PARAMS) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 		    !strcmp(pev->args[i].var, PROBE_ARG_VARS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) /* Return true if this perf_probe_event requires debuginfo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	if (pev->point.file || pev->point.line || pev->point.lazy_line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	if (perf_probe_with_var(pev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) /* Parse probe_events event into struct probe_point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	struct probe_trace_point *tp = &tev->point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	char pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 	int ret, i, argc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	char **argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	pr_debug("Parsing probe_events: %s\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	argv = argv_split(cmd, &argc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 	if (!argv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 		pr_debug("Failed to split arguments.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	if (argc < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 		semantic_error("Too few probe arguments.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 		ret = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 	/* Scan event and group name. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 	argv0_str = strdup(argv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	if (argv0_str == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 	fmt1_str = strtok_r(argv0_str, ":", &fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 	fmt2_str = strtok_r(NULL, "/", &fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 	fmt3_str = strtok_r(NULL, " \t", &fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 	if (fmt1_str == NULL || fmt2_str == NULL || fmt3_str == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 		semantic_error("Failed to parse event name: %s\n", argv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 	pr = fmt1_str[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 	tev->group = strdup(fmt2_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	tev->event = strdup(fmt3_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 	if (tev->group == NULL || tev->event == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 	pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 	tp->retprobe = (pr == 'r');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	/* Scan module name(if there), function name and offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 	p = strchr(argv[1], ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 	if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 		tp->module = strndup(argv[1], p - argv[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 		if (!tp->module) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 		tev->uprobes = (tp->module[0] == '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 		p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 		p = argv[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	fmt1_str = strtok_r(p, "+", &fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	/* only the address started with 0x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 	if (fmt1_str[0] == '0')	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 		 * Fix a special case:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 		 * if address == 0, kernel reports something like:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 		 * p:probe_libc/abs_0 /lib/libc-2.18.so:0x          (null) arg1=%ax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 		 * Newer kernel may fix that, but we want to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 		 * support old kernel also.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 		if (strcmp(fmt1_str, "0x") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 			if (!argv[2] || strcmp(argv[2], "(null)")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 				ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 			tp->address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 			free(argv[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 			for (i = 2; argv[i + 1] != NULL; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 				argv[i] = argv[i + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 			argv[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 			argc -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 			tp->address = strtoul(fmt1_str, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 		/* Only the symbol-based probe has offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 		tp->symbol = strdup(fmt1_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 		if (tp->symbol == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 		fmt2_str = strtok_r(NULL, "", &fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 		if (fmt2_str == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 			tp->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 			tp->offset = strtoul(fmt2_str, NULL, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	if (tev->uprobes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 		fmt2_str = strchr(p, '(');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 		if (fmt2_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 			tp->ref_ctr_offset = strtoul(fmt2_str + 1, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	tev->nargs = argc - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	if (tev->args == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	for (i = 0; i < tev->nargs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 		p = strchr(argv[i + 2], '=');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 		if (p)	/* We don't need which register is assigned. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 			*p++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 			p = argv[i + 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 		tev->args[i].name = strdup(argv[i + 2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 		/* TODO: parse regs and offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 		tev->args[i].value = strdup(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 		if (tev->args[i].name == NULL || tev->args[i].value == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	free(argv0_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	argv_free(argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) /* Compose only probe arg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) char *synthesize_perf_probe_arg(struct perf_probe_arg *pa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 	struct perf_probe_arg_field *field = pa->field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 	struct strbuf buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	char *ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	if (strbuf_init(&buf, 64) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	if (pa->name && pa->var)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 		err = strbuf_addf(&buf, "%s=%s", pa->name, pa->var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 		err = strbuf_addstr(&buf, pa->name ?: pa->var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 	while (field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 		if (field->name[0] == '[')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 			err = strbuf_addstr(&buf, field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 			err = strbuf_addf(&buf, "%s%s", field->ref ? "->" : ".",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 					  field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 		field = field->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 	if (pa->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 		if (strbuf_addf(&buf, ":%s", pa->type) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 	ret = strbuf_detach(&buf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	strbuf_release(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) /* Compose only probe point (not argument) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) char *synthesize_perf_probe_point(struct perf_probe_point *pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 	struct strbuf buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 	char *tmp, *ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 	int len, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 	if (strbuf_init(&buf, 64) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	if (pp->function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 		if (strbuf_addstr(&buf, pp->function) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 		if (pp->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 			err = strbuf_addf(&buf, "+%lu", pp->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 		else if (pp->line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 			err = strbuf_addf(&buf, ":%d", pp->line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 		else if (pp->retprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 			err = strbuf_addstr(&buf, "%return");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	if (pp->file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 		tmp = pp->file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 		len = strlen(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 		if (len > 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 			tmp = strchr(pp->file + len - 30, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 			tmp = tmp ? tmp + 1 : pp->file + len - 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 		err = strbuf_addf(&buf, "@%s", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 		if (!err && !pp->function && pp->line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 			err = strbuf_addf(&buf, ":%d", pp->line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 		ret = strbuf_detach(&buf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 	strbuf_release(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) char *synthesize_perf_probe_command(struct perf_probe_event *pev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	struct strbuf buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 	char *tmp, *ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 	if (strbuf_init(&buf, 64))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	if (pev->event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 		if (strbuf_addf(&buf, "%s:%s=", pev->group ?: PERFPROBE_GROUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 				pev->event) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	tmp = synthesize_perf_probe_point(&pev->point);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 	if (!tmp || strbuf_addstr(&buf, tmp) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	free(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	for (i = 0; i < pev->nargs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 		tmp = synthesize_perf_probe_arg(pev->args + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 		if (!tmp || strbuf_addf(&buf, " %s", tmp) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 		free(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 	ret = strbuf_detach(&buf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 	strbuf_release(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 					    struct strbuf *buf, int depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 	if (ref->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 		depth = __synthesize_probe_trace_arg_ref(ref->next, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 							 depth + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 		if (depth < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 			return depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	if (ref->user_access)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 		err = strbuf_addf(buf, "%s%ld(", "+u", ref->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 		err = strbuf_addf(buf, "%+ld(", ref->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	return (err < 0) ? err : depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) static int synthesize_probe_trace_arg(struct probe_trace_arg *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 				      struct strbuf *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	struct probe_trace_arg_ref *ref = arg->ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	int depth = 0, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 	/* Argument name or separator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	if (arg->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 		err = strbuf_addf(buf, " %s=", arg->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 		err = strbuf_addch(buf, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	/* Special case: @XXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 	if (arg->value[0] == '@' && arg->ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 			ref = ref->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 	/* Dereferencing arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	if (ref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 		depth = __synthesize_probe_trace_arg_ref(ref, buf, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 		if (depth < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 			return depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	/* Print argument value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 	if (arg->value[0] == '@' && arg->ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 		err = strbuf_addf(buf, "%s%+ld", arg->value, arg->ref->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 		err = strbuf_addstr(buf, arg->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	/* Closing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 	while (!err && depth--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 		err = strbuf_addch(buf, ')');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 	/* Print argument type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 	if (!err && arg->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 		err = strbuf_addf(buf, ":%s", arg->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) synthesize_uprobe_trace_def(struct probe_trace_event *tev, struct strbuf *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 	struct probe_trace_point *tp = &tev->point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	err = strbuf_addf(buf, "%s:0x%lx", tp->module, tp->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 	if (err >= 0 && tp->ref_ctr_offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 		if (!uprobe_ref_ctr_is_supported())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 		err = strbuf_addf(buf, "(0x%lx)", tp->ref_ctr_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	return err >= 0 ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) char *synthesize_probe_trace_command(struct probe_trace_event *tev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 	struct probe_trace_point *tp = &tev->point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 	struct strbuf buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 	char *ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	/* Uprobes must have tp->module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 	if (tev->uprobes && !tp->module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 	if (strbuf_init(&buf, 32) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 	if (strbuf_addf(&buf, "%c:%s/%s ", tp->retprobe ? 'r' : 'p',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 			tev->group, tev->event) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 	 * If tp->address == 0, then this point must be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 	 * absolute address uprobe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 	 * try_to_find_absolute_address() should have made
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	 * tp->symbol to "0x0".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 	if (tev->uprobes && !tp->address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 		if (!tp->symbol || strcmp(tp->symbol, "0x0"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 	/* Use the tp->address for uprobes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 	if (tev->uprobes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 		err = synthesize_uprobe_trace_def(tev, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 	} else if (!strncmp(tp->symbol, "0x", 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 		/* Absolute address. See try_to_find_absolute_address() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 		err = strbuf_addf(&buf, "%s%s0x%lx", tp->module ?: "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 				  tp->module ? ":" : "", tp->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 		err = strbuf_addf(&buf, "%s%s%s+%lu", tp->module ?: "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 				tp->module ? ":" : "", tp->symbol, tp->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 	for (i = 0; i < tev->nargs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 		if (synthesize_probe_trace_arg(&tev->args[i], &buf) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 	ret = strbuf_detach(&buf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 	strbuf_release(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 					  struct perf_probe_point *pp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 					  bool is_kprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 	struct symbol *sym = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 	struct map *map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 	u64 addr = tp->address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 	int ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	if (!is_kprobe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 		map = dso__new_map(tp->module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 		if (!map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 		sym = map__find_symbol(map, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 		if (tp->symbol && !addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 			if (kernel_get_symbol_address_by_name(tp->symbol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 						&addr, true, false) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 		if (addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 			addr += tp->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 			sym = machine__find_kernel_symbol(host_machine, addr, &map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 	if (!sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 	pp->retprobe = tp->retprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	pp->offset = addr - map->unmap_ip(map, sym->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	pp->function = strdup(sym->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 	ret = pp->function ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	if (map && !is_kprobe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 		map__put(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) static int convert_to_perf_probe_point(struct probe_trace_point *tp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 				       struct perf_probe_point *pp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 				       bool is_kprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 	char buf[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	ret = find_perf_probe_point_from_dwarf(tp, pp, is_kprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	ret = find_perf_probe_point_from_map(tp, pp, is_kprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 	pr_debug("Failed to find probe point from both of dwarf and map.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	if (tp->symbol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 		pp->function = strdup(tp->symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 		pp->offset = tp->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 		ret = e_snprintf(buf, 128, "0x%" PRIx64, (u64)tp->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 		pp->function = strdup(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 		pp->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 	if (pp->function == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 	pp->retprobe = tp->retprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) static int convert_to_perf_probe_event(struct probe_trace_event *tev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 			       struct perf_probe_event *pev, bool is_kprobe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 	struct strbuf buf = STRBUF_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 	/* Convert event/group name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 	pev->event = strdup(tev->event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 	pev->group = strdup(tev->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	if (pev->event == NULL || pev->group == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 	/* Convert trace_point to probe_point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 	ret = convert_to_perf_probe_point(&tev->point, &pev->point, is_kprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	/* Convert trace_arg to probe_arg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 	pev->nargs = tev->nargs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 	pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 	if (pev->args == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	for (i = 0; i < tev->nargs && ret >= 0; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 		if (tev->args[i].name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 			pev->args[i].name = strdup(tev->args[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 			if ((ret = strbuf_init(&buf, 32)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 			ret = synthesize_probe_trace_arg(&tev->args[i], &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 			pev->args[i].name = strbuf_detach(&buf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 		if (pev->args[i].name == NULL && ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		clear_perf_probe_event(pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) void clear_perf_probe_event(struct perf_probe_event *pev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 	struct perf_probe_arg_field *field, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 	zfree(&pev->event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	zfree(&pev->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	zfree(&pev->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 	clear_perf_probe_point(&pev->point);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 	for (i = 0; i < pev->nargs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 		zfree(&pev->args[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 		zfree(&pev->args[i].var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 		zfree(&pev->args[i].type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 		field = pev->args[i].field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 		while (field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 			next = field->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 			zfree(&field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 			free(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 			field = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 	pev->nargs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	zfree(&pev->args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) #define strdup_or_goto(str, label)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) ({ char *__p = NULL; if (str && !(__p = strdup(str))) goto label; __p; })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) static int perf_probe_point__copy(struct perf_probe_point *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 				  struct perf_probe_point *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 	dst->file = strdup_or_goto(src->file, out_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	dst->function = strdup_or_goto(src->function, out_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 	dst->lazy_line = strdup_or_goto(src->lazy_line, out_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 	dst->line = src->line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 	dst->retprobe = src->retprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 	dst->offset = src->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	clear_perf_probe_point(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) static int perf_probe_arg__copy(struct perf_probe_arg *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 				struct perf_probe_arg *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 	struct perf_probe_arg_field *field, **ppfield;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 	dst->name = strdup_or_goto(src->name, out_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	dst->var = strdup_or_goto(src->var, out_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 	dst->type = strdup_or_goto(src->type, out_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	field = src->field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 	ppfield = &(dst->field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 	while (field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 		*ppfield = zalloc(sizeof(*field));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 		if (!*ppfield)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 		(*ppfield)->name = strdup_or_goto(field->name, out_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 		(*ppfield)->index = field->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 		(*ppfield)->ref = field->ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 		field = field->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 		ppfield = &((*ppfield)->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) int perf_probe_event__copy(struct perf_probe_event *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 			   struct perf_probe_event *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 	dst->event = strdup_or_goto(src->event, out_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	dst->group = strdup_or_goto(src->group, out_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 	dst->target = strdup_or_goto(src->target, out_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	dst->uprobes = src->uprobes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 	if (perf_probe_point__copy(&dst->point, &src->point) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	dst->args = zalloc(sizeof(struct perf_probe_arg) * src->nargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	if (!dst->args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 	dst->nargs = src->nargs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	for (i = 0; i < src->nargs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 		if (perf_probe_arg__copy(&dst->args[i], &src->args[i]) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 	clear_perf_probe_event(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) void clear_probe_trace_event(struct probe_trace_event *tev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	struct probe_trace_arg_ref *ref, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 	zfree(&tev->event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 	zfree(&tev->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 	zfree(&tev->point.symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 	zfree(&tev->point.realname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	zfree(&tev->point.module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	for (i = 0; i < tev->nargs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 		zfree(&tev->args[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 		zfree(&tev->args[i].value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 		zfree(&tev->args[i].type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 		ref = tev->args[i].ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 		while (ref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 			next = ref->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 			free(ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 			ref = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	zfree(&tev->args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 	tev->nargs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) struct kprobe_blacklist_node {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	unsigned long start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 	unsigned long end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 	char *symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) static void kprobe_blacklist__delete(struct list_head *blacklist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	struct kprobe_blacklist_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 	while (!list_empty(blacklist)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 		node = list_first_entry(blacklist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 					struct kprobe_blacklist_node, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 		list_del_init(&node->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 		zfree(&node->symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 		free(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) static int kprobe_blacklist__load(struct list_head *blacklist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 	struct kprobe_blacklist_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 	const char *__debugfs = debugfs__mountpoint();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 	char buf[PATH_MAX], *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 	FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 	if (__debugfs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 		return -ENOTSUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 	ret = e_snprintf(buf, PATH_MAX, "%s/kprobes/blacklist", __debugfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 	fp = fopen(buf, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 	if (!fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 		return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 	while (fgets(buf, PATH_MAX, fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 		node = zalloc(sizeof(*node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 		if (!node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 		INIT_LIST_HEAD(&node->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 		list_add_tail(&node->list, blacklist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 		if (sscanf(buf, "0x%lx-0x%lx", &node->start, &node->end) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 		p = strchr(buf, '\t');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 		if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 			p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 			if (p[strlen(p) - 1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 				p[strlen(p) - 1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 			p = (char *)"unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 		node->symbol = strdup(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 		if (!node->symbol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 		pr_debug2("Blacklist: 0x%lx-0x%lx, %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 			  node->start, node->end, node->symbol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 		ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 		kprobe_blacklist__delete(blacklist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) static struct kprobe_blacklist_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) kprobe_blacklist__find_by_address(struct list_head *blacklist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 				  unsigned long address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 	struct kprobe_blacklist_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 	list_for_each_entry(node, blacklist, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 		if (node->start <= address && address < node->end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 			return node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) static LIST_HEAD(kprobe_blacklist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) static void kprobe_blacklist__init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 	if (!list_empty(&kprobe_blacklist))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 	if (kprobe_blacklist__load(&kprobe_blacklist) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 		pr_debug("No kprobe blacklist support, ignored\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) static void kprobe_blacklist__release(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 	kprobe_blacklist__delete(&kprobe_blacklist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) static bool kprobe_blacklist__listed(unsigned long address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	return !!kprobe_blacklist__find_by_address(&kprobe_blacklist, address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) static int perf_probe_event__sprintf(const char *group, const char *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 				     struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 				     const char *module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 				     struct strbuf *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 	char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	if (asprintf(&buf, "%s:%s", group, event) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 		return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 	ret = strbuf_addf(result, "  %-20s (on ", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 	free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 	/* Synthesize only event probe point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	buf = synthesize_perf_probe_point(&pev->point);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	ret = strbuf_addstr(result, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	if (!ret && module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 		ret = strbuf_addf(result, " in %s", module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 	if (!ret && pev->nargs > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 		ret = strbuf_add(result, " with", 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 		for (i = 0; !ret && i < pev->nargs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 			buf = synthesize_perf_probe_arg(&pev->args[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 			if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 				return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 			ret = strbuf_addf(result, " %s", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 			free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 		ret = strbuf_addch(result, ')');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) /* Show an event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) int show_perf_probe_event(const char *group, const char *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 			  struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 			  const char *module, bool use_stdout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 	struct strbuf buf = STRBUF_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	ret = perf_probe_event__sprintf(group, event, pev, module, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 		if (use_stdout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 			printf("%s\n", buf.buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 			pr_info("%s\n", buf.buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 	strbuf_release(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) static bool filter_probe_trace_event(struct probe_trace_event *tev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 				     struct strfilter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	char tmp[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 	/* At first, check the event name itself */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	if (strfilter__compare(filter, tev->event))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	/* Next, check the combination of name and group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 	if (e_snprintf(tmp, 128, "%s:%s", tev->group, tev->event) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 	return strfilter__compare(filter, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) static int __show_perf_probe_events(int fd, bool is_kprobe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 				    struct strfilter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 	struct probe_trace_event tev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 	struct perf_probe_event pev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	struct strlist *rawlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 	struct str_node *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 	memset(&tev, 0, sizeof(tev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	memset(&pev, 0, sizeof(pev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	rawlist = probe_file__get_rawlist(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 	if (!rawlist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	strlist__for_each_entry(ent, rawlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 		ret = parse_probe_trace_command(ent->s, &tev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 		if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 			if (!filter_probe_trace_event(&tev, filter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 				goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 			ret = convert_to_perf_probe_event(&tev, &pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 								is_kprobe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 				goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 			ret = show_perf_probe_event(pev.group, pev.event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 						    &pev, tev.point.module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 						    true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 		clear_perf_probe_event(&pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 		clear_probe_trace_event(&tev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 	strlist__delete(rawlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 	/* Cleanup cached debuginfo if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 	debuginfo_cache__exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) /* List up current perf-probe events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) int show_perf_probe_events(struct strfilter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 	int kp_fd, up_fd, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 	setup_pager();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 	if (probe_conf.cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 		return probe_cache__show_all_caches(filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 	ret = init_probe_symbol_maps(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 	ret = probe_file__open_both(&kp_fd, &up_fd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 	if (kp_fd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 		ret = __show_perf_probe_events(kp_fd, true, filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 	if (up_fd >= 0 && ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 		ret = __show_perf_probe_events(up_fd, false, filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 	if (kp_fd > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 		close(kp_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	if (up_fd > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 		close(up_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 	exit_probe_symbol_maps();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) static int get_new_event_name(char *buf, size_t len, const char *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 			      struct strlist *namelist, bool ret_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 			      bool allow_suffix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 	char *p, *nbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 	if (*base == '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 		base++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 	nbase = strdup(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 	if (!nbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 	/* Cut off the dot suffixes (e.g. .const, .isra) and version suffixes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 	p = strpbrk(nbase, ".@");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 	if (p && p != nbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 		*p = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 	/* Try no suffix number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 	ret = e_snprintf(buf, len, "%s%s", nbase, ret_event ? "__return" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 		pr_debug("snprintf() failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 	if (!strlist__has_entry(namelist, buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 	if (!allow_suffix) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 		pr_warning("Error: event \"%s\" already exists.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 			   " Hint: Remove existing event by 'perf probe -d'\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 			   "       or force duplicates by 'perf probe -f'\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 			   "       or set 'force=yes' in BPF source.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 			   buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 		ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 	/* Try to add suffix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 	for (i = 1; i < MAX_EVENT_INDEX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 		ret = e_snprintf(buf, len, "%s_%d", nbase, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 			pr_debug("snprintf() failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 		if (!strlist__has_entry(namelist, buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 	if (i == MAX_EVENT_INDEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 		pr_warning("Too many events are on the same function.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 		ret = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 	free(nbase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 	/* Final validation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 	if (ret >= 0 && !is_c_func_name(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 		pr_warning("Internal error: \"%s\" is an invalid event name.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 			   buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) /* Warn if the current kernel's uprobe implementation is old */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) static void warn_uprobe_event_compat(struct probe_trace_event *tev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 	char *buf = synthesize_probe_trace_command(tev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 	struct probe_trace_point *tp = &tev->point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 	if (tp->ref_ctr_offset && !uprobe_ref_ctr_is_supported()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 		pr_warning("A semaphore is associated with %s:%s and "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 			   "seems your kernel doesn't support it.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 			   tev->group, tev->event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 	/* Old uprobe event doesn't support memory dereference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 	if (!tev->uprobes || tev->nargs == 0 || !buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 	for (i = 0; i < tev->nargs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 		if (strglobmatch(tev->args[i].value, "[$@+-]*")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 			pr_warning("Please upgrade your kernel to at least "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 				   "3.14 to have access to feature %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 				   tev->args[i].value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 	free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) /* Set new name from original perf_probe_event and namelist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) static int probe_trace_event__set_name(struct probe_trace_event *tev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 				       struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 				       struct strlist *namelist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 				       bool allow_suffix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 	const char *event, *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	char buf[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 	/* If probe_event or trace_event already have the name, reuse it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 	if (pev->event && !pev->sdt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 		event = pev->event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 	else if (tev->event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 		event = tev->event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 		/* Or generate new one from probe point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 		if (pev->point.function &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 			(strncmp(pev->point.function, "0x", 2) != 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 			!strisglob(pev->point.function))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 			event = pev->point.function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 			event = tev->point.realname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 	if (pev->group && !pev->sdt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 		group = pev->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 	else if (tev->group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 		group = tev->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 		group = PERFPROBE_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 	/* Get an unused new event name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 	ret = get_new_event_name(buf, 64, event, namelist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 				 tev->point.retprobe, allow_suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 	event = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 	tev->event = strdup(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 	tev->group = strdup(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 	if (tev->event == NULL || tev->group == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	 * Add new event name to namelist if multiprobe event is NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 	 * supported, since we have to use new event name for following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 	 * probes in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 	if (!multiprobe_event_is_supported())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 		strlist__add(namelist, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) static int __open_probe_file_and_namelist(bool uprobe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 					  struct strlist **namelist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 	int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 	fd = probe_file__open(PF_FL_RW | (uprobe ? PF_FL_UPROBE : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 	if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 		return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 	/* Get current event names */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 	*namelist = probe_file__get_namelist(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 	if (!(*namelist)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 		pr_debug("Failed to get current event list.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 		close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 	return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) static int __add_probe_trace_events(struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 				     struct probe_trace_event *tevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 				     int ntevs, bool allow_suffix)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 	int i, fd[2] = {-1, -1}, up, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 	struct probe_trace_event *tev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 	struct probe_cache *cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 	struct strlist *namelist[2] = {NULL, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 	struct nscookie nsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 	up = pev->uprobes ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	fd[up] = __open_probe_file_and_namelist(up, &namelist[up]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 	if (fd[up] < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 		return fd[up];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 	for (i = 0; i < ntevs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 		tev = &tevs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 		up = tev->uprobes ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 		if (fd[up] == -1) {	/* Open the kprobe/uprobe_events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 			fd[up] = __open_probe_file_and_namelist(up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 								&namelist[up]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 			if (fd[up] < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 				goto close_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 		/* Skip if the symbol is out of .text or blacklisted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 		if (!tev->point.symbol && !pev->uprobes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 		/* Set new name for tev (and update namelist) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 		ret = probe_trace_event__set_name(tev, pev, namelist[up],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 						  allow_suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 		nsinfo__mountns_enter(pev->nsi, &nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 		ret = probe_file__add_event(fd[up], tev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 		nsinfo__mountns_exit(&nsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 		 * Probes after the first probe which comes from same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 		 * user input are always allowed to add suffix, because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 		 * there might be several addresses corresponding to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 		 * one code line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 		allow_suffix = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 	if (ret == -EINVAL && pev->uprobes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 		warn_uprobe_event_compat(tev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 	if (ret == 0 && probe_conf.cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 		cache = probe_cache__new(pev->target, pev->nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 		if (!cache ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 		    probe_cache__add_entry(cache, pev, tevs, ntevs) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 		    probe_cache__commit(cache) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 			pr_warning("Failed to add event to probe cache\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 		probe_cache__delete(cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) close_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 	for (up = 0; up < 2; up++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 		strlist__delete(namelist[up]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 		if (fd[up] >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 			close(fd[up]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) static int find_probe_functions(struct map *map, char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 				struct symbol **syms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 	int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 	struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 	struct rb_node *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 	const char *norm, *ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 	char *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 	bool cut_version = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 	if (map__load(map) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 	/* If user gives a version, don't cut off the version from symbols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 	if (strchr(name, '@'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 		cut_version = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	map__for_each_symbol(map, sym, tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 		norm = arch__normalize_symbol_name(sym->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 		if (!norm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 		if (cut_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 			/* We don't care about default symbol or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 			ver = strchr(norm, '@');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 			if (ver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 				buf = strndup(norm, ver - norm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 				if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 					return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 				norm = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 		if (strglobmatch(norm, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 			found++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 			if (syms && found < probe_conf.max_probes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 				syms[found - 1] = sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 		if (buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 			zfree(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 	return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) void __weak arch__fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 				struct probe_trace_event *tev __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 				struct map *map __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 				struct symbol *sym __maybe_unused) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969)  * Find probe function addresses from map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970)  * Return an error or the number of found probe_trace_event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 					    struct probe_trace_event **tevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 	struct map *map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 	struct ref_reloc_sym *reloc_sym = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 	struct symbol *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 	struct symbol **syms = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 	struct probe_trace_event *tev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 	struct perf_probe_point *pp = &pev->point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 	struct probe_trace_point *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 	int num_matched_functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 	int ret, i, j, skipped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 	char *mod_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 	map = get_target_map(pev->target, pev->nsi, pev->uprobes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 	if (!map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 	syms = malloc(sizeof(struct symbol *) * probe_conf.max_probes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 	if (!syms) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 	 * Load matched symbols: Since the different local symbols may have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 	 * same name but different addresses, this lists all the symbols.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 	num_matched_functions = find_probe_functions(map, pp->function, syms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	if (num_matched_functions <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 		pr_err("Failed to find symbol %s in %s\n", pp->function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 			pev->target ? : "kernel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 		ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 	} else if (num_matched_functions > probe_conf.max_probes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 		pr_err("Too many functions matched in %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 			pev->target ? : "kernel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 		ret = -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 	/* Note that the symbols in the kmodule are not relocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	if (!pev->uprobes && !pev->target &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 			(!pp->retprobe || kretprobe_offset_is_supported())) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 		reloc_sym = kernel_get_ref_reloc_sym(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 		if (!reloc_sym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 			pr_warning("Relocated base symbol is not found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 	/* Setup result trace-probe-events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 	*tevs = zalloc(sizeof(*tev) * num_matched_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 	if (!*tevs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 	for (j = 0; j < num_matched_functions; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 		sym = syms[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 		if (sym->type != STT_FUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 		/* There can be duplicated symbols in the map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 		for (i = 0; i < j; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 			if (sym->start == syms[i]->start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 				pr_debug("Found duplicated symbol %s @ %" PRIx64 "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 					 sym->name, sym->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 		if (i != j)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 		tev = (*tevs) + ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 		tp = &tev->point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 		if (ret == num_matched_functions) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 			pr_warning("Too many symbols are listed. Skip it.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 		ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 		if (pp->offset > sym->end - sym->start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 			pr_warning("Offset %ld is bigger than the size of %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 				   pp->offset, sym->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 			ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 			goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 		/* Add one probe point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 		tp->address = map->unmap_ip(map, sym->start) + pp->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 		/* Check the kprobe (not in module) is within .text  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 		if (!pev->uprobes && !pev->target &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 		    kprobe_warn_out_range(sym->name, tp->address)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 			tp->symbol = NULL;	/* Skip it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 			skipped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 		} else if (reloc_sym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 			tp->symbol = strdup_or_goto(reloc_sym->name, nomem_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 			tp->offset = tp->address - reloc_sym->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 			tp->symbol = strdup_or_goto(sym->name, nomem_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 			tp->offset = pp->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 		tp->realname = strdup_or_goto(sym->name, nomem_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 		tp->retprobe = pp->retprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 		if (pev->target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 			if (pev->uprobes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 				tev->point.module = strdup_or_goto(pev->target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 								   nomem_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 				mod_name = find_module_name(pev->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 				tev->point.module =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 					strdup(mod_name ? mod_name : pev->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 				free(mod_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 				if (!tev->point.module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 					goto nomem_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 		tev->uprobes = pev->uprobes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 		tev->nargs = pev->nargs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 		if (tev->nargs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 			tev->args = zalloc(sizeof(struct probe_trace_arg) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 					   tev->nargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 			if (tev->args == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 				goto nomem_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 		for (i = 0; i < tev->nargs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 			if (pev->args[i].name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 				tev->args[i].name =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 					strdup_or_goto(pev->args[i].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 							nomem_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 			tev->args[i].value = strdup_or_goto(pev->args[i].var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 							    nomem_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 			if (pev->args[i].type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 				tev->args[i].type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 					strdup_or_goto(pev->args[i].type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 							nomem_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 		arch__fix_tev_from_maps(pev, tev, map, sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 	if (ret == skipped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 		ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 	map__put(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 	free(syms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) nomem_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 	ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 	clear_probe_trace_events(*tevs, num_matched_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 	zfree(tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) static int try_to_find_absolute_address(struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 					struct probe_trace_event **tevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 	struct perf_probe_point *pp = &pev->point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 	struct probe_trace_event *tev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 	struct probe_trace_point *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 	if (!(pev->point.function && !strncmp(pev->point.function, "0x", 2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 	if (perf_probe_event_need_dwarf(pev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 	 * This is 'perf probe /lib/libc.so 0xabcd'. Try to probe at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 	 * absolute address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 	 * Only one tev can be generated by this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 	*tevs = zalloc(sizeof(*tev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 	if (!*tevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 	tev = *tevs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 	tp = &tev->point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 	 * Don't use tp->offset, use address directly, because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 	 * in synthesize_probe_trace_command() address cannot be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 	 * zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 	tp->address = pev->point.abs_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 	tp->retprobe = pp->retprobe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 	tev->uprobes = pev->uprobes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 	err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 	 * Give it a '0x' leading symbol name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 	 * In __add_probe_trace_events, a NULL symbol is interpreted as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 	 * invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 	if (asprintf(&tp->symbol, "0x%lx", tp->address) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 	/* For kprobe, check range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 	if ((!tev->uprobes) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 	    (kprobe_warn_out_range(tev->point.symbol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 				   tev->point.address))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 		err = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 	if (asprintf(&tp->realname, "abs_%lx", tp->address) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 	if (pev->target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 		tp->module = strdup(pev->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 		if (!tp->module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 			goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 	if (tev->group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 		tev->group = strdup(pev->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 		if (!tev->group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 			goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 	if (pev->event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 		tev->event = strdup(pev->event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 		if (!tev->event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 			goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 	tev->nargs = pev->nargs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 	tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 	if (!tev->args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 	for (i = 0; i < tev->nargs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 		copy_to_probe_trace_arg(&tev->args[i], &pev->args[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) errout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 	clear_probe_trace_events(*tevs, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 	*tevs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) /* Concatinate two arrays */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) static void *memcat(void *a, size_t sz_a, void *b, size_t sz_b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 	void *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 	ret = malloc(sz_a + sz_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 		memcpy(ret, a, sz_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 		memcpy(ret + sz_a, b, sz_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) concat_probe_trace_events(struct probe_trace_event **tevs, int *ntevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 			  struct probe_trace_event **tevs2, int ntevs2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 	struct probe_trace_event *new_tevs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 	if (*ntevs == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 		*tevs = *tevs2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 		*ntevs = ntevs2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 		*tevs2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 	if (*ntevs + ntevs2 > probe_conf.max_probes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 		ret = -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 		/* Concatinate the array of probe_trace_event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 		new_tevs = memcat(*tevs, (*ntevs) * sizeof(**tevs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 				  *tevs2, ntevs2 * sizeof(**tevs2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 		if (!new_tevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 			ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 			free(*tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 			*tevs = new_tevs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 			*ntevs += ntevs2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 		clear_probe_trace_events(*tevs2, ntevs2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 	zfree(tevs2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275)  * Try to find probe_trace_event from given probe caches. Return the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276)  * of cached events found, if an error occurs return the error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) static int find_cached_events(struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 			      struct probe_trace_event **tevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 			      const char *target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 	struct probe_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 	struct probe_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 	struct probe_trace_event *tmp_tevs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 	int ntevs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 	cache = probe_cache__new(target, pev->nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 	/* Return 0 ("not found") if the target has no probe cache. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 	if (!cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 	for_each_probe_cache_entry(entry, cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 		/* Skip the cache entry which has no name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 		if (!entry->pev.event || !entry->pev.group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 		if ((!pev->group || strglobmatch(entry->pev.group, pev->group)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 		    strglobmatch(entry->pev.event, pev->event)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 			ret = probe_cache_entry__get_event(entry, &tmp_tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 			if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 				ret = concat_probe_trace_events(tevs, &ntevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 								&tmp_tevs, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 	probe_cache__delete(cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 		clear_probe_trace_events(*tevs, ntevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 		zfree(tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 		ret = ntevs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 		if (ntevs > 0 && target && target[0] == '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 			pev->uprobes = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) /* Try to find probe_trace_event from all probe caches */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) static int find_cached_events_all(struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 				   struct probe_trace_event **tevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 	struct probe_trace_event *tmp_tevs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 	struct strlist *bidlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 	struct str_node *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 	char *pathname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 	int ntevs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 	/* Get the buildid list of all valid caches */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 	bidlist = build_id_cache__list_all(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 	if (!bidlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 		ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 		pr_debug("Failed to get buildids: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 	strlist__for_each_entry(nd, bidlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 		pathname = build_id_cache__origname(nd->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 		ret = find_cached_events(pev, &tmp_tevs, pathname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 		/* In the case of cnt == 0, we just skip it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 		if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 			ret = concat_probe_trace_events(tevs, &ntevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 							&tmp_tevs, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 		free(pathname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 	strlist__delete(bidlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 		clear_probe_trace_events(*tevs, ntevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 		zfree(tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 		ret = ntevs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 					      struct probe_trace_event **tevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 	struct probe_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 	struct probe_cache_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 	struct probe_trace_event *tev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 	struct str_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 	if (pev->sdt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 		/* For SDT/cached events, we use special search functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 		if (!pev->target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 			return find_cached_events_all(pev, tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 			return find_cached_events(pev, tevs, pev->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 	cache = probe_cache__new(pev->target, pev->nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 	if (!cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 	entry = probe_cache__find(cache, pev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 	if (!entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 		/* SDT must be in the cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 		ret = pev->sdt ? -ENOENT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 	ret = strlist__nr_entries(entry->tevlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) 	if (ret > probe_conf.max_probes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 		pr_debug("Too many entries matched in the cache of %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) 			 pev->target ? : "kernel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 		ret = -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 	*tevs = zalloc(ret * sizeof(*tev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) 	if (!*tevs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) 	strlist__for_each_entry(node, entry->tevlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 		tev = &(*tevs)[i++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 		ret = parse_probe_trace_command(node->s, tev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 		/* Set the uprobes attribute as same as original */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 		tev->uprobes = pev->uprobes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 	ret = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 	probe_cache__delete(cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) static int convert_to_probe_trace_events(struct perf_probe_event *pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 					 struct probe_trace_event **tevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 	if (!pev->group && !pev->sdt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 		/* Set group name if not given */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 		if (!pev->uprobes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 			pev->group = strdup(PERFPROBE_GROUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 			ret = pev->group ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 			ret = convert_exec_to_group(pev->target, &pev->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 		if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 			pr_warning("Failed to make a group name.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 	ret = try_to_find_absolute_address(pev, tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 	if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 	/* At first, we need to lookup cache entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 	ret = find_probe_trace_events_from_cache(pev, tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 	if (ret > 0 || pev->sdt)	/* SDT can be found only in the cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 		return ret == 0 ? -ENOENT : ret; /* Found in probe cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 	/* Convert perf_probe_event with debuginfo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 	ret = try_to_find_probe_trace_events(pev, tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 	if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 		return ret;	/* Found in debuginfo or got an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 	return find_probe_trace_events_from_map(pev, tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 	/* Loop 1: convert all events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 	for (i = 0; i < npevs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 		/* Init kprobe blacklist if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) 		if (!pevs[i].uprobes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 			kprobe_blacklist__init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 		/* Convert with or without debuginfo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 		ret  = convert_to_probe_trace_events(&pevs[i], &pevs[i].tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 		pevs[i].ntevs = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 	/* This just release blacklist only if allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 	kprobe_blacklist__release();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) static int show_probe_trace_event(struct probe_trace_event *tev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 	char *buf = synthesize_probe_trace_command(tev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) 	if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 		pr_debug("Failed to synthesize probe trace event.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 	/* Showing definition always go stdout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) 	printf("%s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) 	free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) int show_probe_trace_events(struct perf_probe_event *pevs, int npevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 	struct strlist *namelist = strlist__new(NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 	struct probe_trace_event *tev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 	struct perf_probe_event *pev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 	int i, j, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 	if (!namelist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 	for (j = 0; j < npevs && !ret; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 		pev = &pevs[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 		for (i = 0; i < pev->ntevs && !ret; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 			tev = &pev->tevs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 			/* Skip if the symbol is out of .text or blacklisted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 			if (!tev->point.symbol && !pev->uprobes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 			/* Set new name for tev (and update namelist) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 			ret = probe_trace_event__set_name(tev, pev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 							  namelist, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 			if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 				ret = show_probe_trace_event(tev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 	strlist__delete(namelist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 	int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 	/* Loop 2: add all events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 	for (i = 0; i < npevs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 		ret = __add_probe_trace_events(&pevs[i], pevs[i].tevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 					       pevs[i].ntevs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 					       probe_conf.force_add);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 	struct perf_probe_event *pev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 	/* Loop 3: cleanup and free trace events  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 	for (i = 0; i < npevs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 		pev = &pevs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 		for (j = 0; j < pevs[i].ntevs; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 			clear_probe_trace_event(&pevs[i].tevs[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 		zfree(&pevs[i].tevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 		pevs[i].ntevs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 		nsinfo__zput(pev->nsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 		clear_perf_probe_event(&pevs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) int add_perf_probe_events(struct perf_probe_event *pevs, int npevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 	ret = init_probe_symbol_maps(pevs->uprobes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 	ret = convert_perf_probe_events(pevs, npevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 	if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 		ret = apply_perf_probe_events(pevs, npevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 	cleanup_perf_probe_events(pevs, npevs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) 	exit_probe_symbol_maps();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) int del_perf_probe_events(struct strfilter *filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) 	int ret, ret2, ufd = -1, kfd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) 	char *str = strfilter__string(filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) 	if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 	/* Get current event names */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 	ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 	ret = probe_file__del_events(kfd, filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 	if (ret < 0 && ret != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 	ret2 = probe_file__del_events(ufd, filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 	if (ret2 < 0 && ret2 != -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 		ret = ret2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 	if (kfd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) 		close(kfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 	if (ufd >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 		close(ufd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 	free(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) int show_available_funcs(const char *target, struct nsinfo *nsi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) 			 struct strfilter *_filter, bool user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609)         struct rb_node *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 	struct map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 	ret = init_probe_symbol_maps(user);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 	/* Get a symbol map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 	map = get_target_map(target, nsi, user);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 	if (!map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 		pr_err("Failed to get a map for %s\n", (target) ? : "kernel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 	ret = map__load(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 		if (ret == -2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 			char *str = strfilter__string(_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 			pr_err("Failed to find symbols matched to \"%s\"\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 			       str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) 			free(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 			pr_err("Failed to load symbols in %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 			       (target) ? : "kernel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) 	if (!dso__sorted_by_name(map->dso))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 		dso__sort_by_name(map->dso);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 	/* Show all (filtered) symbols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 	setup_pager();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 	for (nd = rb_first_cached(&map->dso->symbol_names); nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 	     nd = rb_next(nd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) 		struct symbol_name_rb_node *pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 		if (strfilter__compare(_filter, pos->sym.name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 			printf("%s\n", pos->sym.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 	map__put(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 	exit_probe_symbol_maps();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) int copy_to_probe_trace_arg(struct probe_trace_arg *tvar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 			    struct perf_probe_arg *pvar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 	tvar->value = strdup(pvar->var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) 	if (tvar->value == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 	if (pvar->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 		tvar->type = strdup(pvar->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) 		if (tvar->type == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 	if (pvar->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 		tvar->name = strdup(pvar->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 		if (tvar->name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 		tvar->name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) }