^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) }