• Home
  • Raw
  • Download

Lines Matching +full:end +full:- +full:point

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * probe-event.c : perf-probe definition to probe_events format converter
22 #include "build-id.h"
35 #include "trace-event.h" /* For __maybe_unused */
36 #include "probe-event.h"
37 #include "probe-finder.h"
38 #include "probe-file.h"
68 ret = -E2BIG; in e_snprintf()
96 ret = -1; in init_probe_symbol_maps()
126 return kmap->ref_reloc_sym; in kernel_get_ref_reloc_sym()
138 if (reloc_sym && strcmp(name, reloc_sym->name) == 0) in kernel_get_symbol_address_by_name()
139 *addr = (!map__reloc(map) || reloc) ? reloc_sym->addr : in kernel_get_symbol_address_by_name()
140 reloc_sym->unrelocated_addr; in kernel_get_symbol_address_by_name()
144 return -ENOENT; in kernel_get_symbol_address_by_name()
145 *addr = map__unmap_ip(map, sym->start) - in kernel_get_symbol_address_by_name()
146 ((reloc) ? 0 : map__reloc(map)) - in kernel_get_symbol_address_by_name()
157 /* A file path -- this is an offline module */ in kernel_get_module_map()
169 struct dso *dso = map__dso(pos->map); in kernel_get_module_map()
170 const char *short_name = dso->short_name; in kernel_get_module_map()
171 u16 short_name_len = dso->short_name_len; in kernel_get_module_map()
174 short_name_len - 2) == 0 && in kernel_get_module_map()
175 module[short_name_len - 2] == '\0') { in kernel_get_module_map()
176 return map__get(pos->map); in kernel_get_module_map()
192 mutex_lock(&dso->lock); in get_target_map()
193 nsinfo__put(dso->nsinfo); in get_target_map()
194 dso->nsinfo = nsinfo__get(nsi); in get_target_map()
195 mutex_unlock(&dso->lock); in get_target_map()
211 return -ENOMEM; in convert_exec_to_group()
215 ret = -EINVAL; in convert_exec_to_group()
231 ret = *result ? 0 : -ENOMEM; in convert_exec_to_group()
240 zfree(&pp->file); in clear_perf_probe_point()
241 zfree(&pp->function); in clear_perf_probe_point()
242 zfree(&pp->lazy_line); in clear_perf_probe_point()
307 if (!data || !data->d_buf) in find_module_name()
316 * exposed to user-space. Offset of 'name' has remained same from long in find_module_name()
324 mod_name = strdup((char *)data->d_buf + name_offset); in find_module_name()
352 return -ENOENT; in kernel_get_module_dso()
357 if (!dso->has_build_id) in kernel_get_module_dso()
361 dso->load_errno = 0; in kernel_get_module_dso()
374 * symbol from map, we can translate the address back to the probe point.
385 int ret = -ENOENT; in find_alternative_probe_point()
388 /* This can work only for function-name based one */ in find_alternative_probe_point()
389 if (!pp->function || pp->file) in find_alternative_probe_point()
390 return -ENOTSUP; in find_alternative_probe_point()
394 return -EINVAL; in find_alternative_probe_point()
397 map__for_each_symbol_by_name(map, pp->function, sym, idx) { in find_alternative_probe_point()
399 address = sym->start; in find_alternative_probe_point()
400 if (sym->type == STT_GNU_IFUNC) in find_alternative_probe_point()
403 pp->function); in find_alternative_probe_point()
405 address = map__unmap_ip(map, sym->start) - map__reloc(map); in find_alternative_probe_point()
409 ret = -ENOENT; in find_alternative_probe_point()
413 pp->function, address); in find_alternative_probe_point()
417 ret = (!ret) ? -ENOENT : ret; in find_alternative_probe_point()
419 result->offset += pp->offset; in find_alternative_probe_point()
420 result->line += pp->line; in find_alternative_probe_point()
421 result->retprobe = pp->retprobe; in find_alternative_probe_point()
437 memcpy(tmp, &pev->point, sizeof(*tmp)); in get_alternative_probe_event()
438 memset(&pev->point, 0, sizeof(pev->point)); in get_alternative_probe_event()
439 ret = find_alternative_probe_point(dinfo, tmp, &pev->point, pev->target, in get_alternative_probe_event()
440 pev->nsi, pev->uprobes); in get_alternative_probe_event()
442 memcpy(&pev->point, tmp, sizeof(*tmp)); in get_alternative_probe_event()
451 struct perf_probe_point pp = { .function = lr->function, in get_alternative_line_range()
452 .file = lr->file, in get_alternative_line_range()
453 .line = lr->start }; in get_alternative_line_range()
459 if (lr->end != INT_MAX) in get_alternative_line_range()
460 len = lr->end - lr->start; in get_alternative_line_range()
464 lr->function = result.function; in get_alternative_line_range()
465 lr->file = result.file; in get_alternative_line_range()
466 lr->start = result.line; in get_alternative_line_range()
467 if (lr->end != INT_MAX) in get_alternative_line_range()
468 lr->end = lr->start + len; in get_alternative_line_range()
488 build_id__sprintf(&dso->bid, sbuild_id); in open_from_debuginfod()
531 if (!dso || dso->load_errno == 0) { in open_debuginfo()
532 if (!str_error_r(-err, reason, STRERR_BUFSIZE)) in open_debuginfo()
548 path = dso->long_name; in open_debuginfo()
557 pr_warning("Rebuild with -g, "); in open_debuginfo()
609 int fd, ret = -ENOENT; in get_text_start_address()
616 return -errno; in get_text_start_address()
620 ret = -EINVAL; in get_text_start_address()
630 *address = shdr.sh_addr - shdr.sh_offset; in get_text_start_address()
641 * Convert trace point to probe point with debuginfo
649 u64 addr = tp->address; in find_perf_probe_point_from_dwarf()
650 int ret = -ENOENT; in find_perf_probe_point_from_dwarf()
655 ret = -EINVAL; in find_perf_probe_point_from_dwarf()
658 ret = get_text_start_address(tp->module, &stext, NULL); in find_perf_probe_point_from_dwarf()
662 } else if (tp->symbol) { in find_perf_probe_point_from_dwarf()
664 ret = kernel_get_symbol_address_by_name(tp->symbol, &addr, in find_perf_probe_point_from_dwarf()
665 false, !!tp->module); in find_perf_probe_point_from_dwarf()
668 addr += tp->offset; in find_perf_probe_point_from_dwarf()
672 tp->module ? : "kernel"); in find_perf_probe_point_from_dwarf()
674 dinfo = debuginfo_cache__open(tp->module, verbose <= 0); in find_perf_probe_point_from_dwarf()
678 ret = -ENOENT; in find_perf_probe_point_from_dwarf()
681 pp->retprobe = tp->retprobe; in find_perf_probe_point_from_dwarf()
686 return ret ? : -ENOENT; in find_perf_probe_point_from_dwarf()
694 u64 addr = tp->address - offs; in post_process_probe_trace_point()
702 return (symbol_conf.ignore_vmlinux_buildid) ? 0 : -ENOENT; in post_process_probe_trace_point()
705 if (strcmp(sym->name, tp->symbol)) { in post_process_probe_trace_point()
707 if (!tp->realname) in post_process_probe_trace_point()
708 tp->realname = tp->symbol; in post_process_probe_trace_point()
710 free(tp->symbol); in post_process_probe_trace_point()
711 tp->symbol = strdup(sym->name); in post_process_probe_trace_point()
712 if (!tp->symbol) in post_process_probe_trace_point()
713 return -ENOMEM; in post_process_probe_trace_point()
715 tp->offset = addr - sym->start; in post_process_probe_trace_point()
716 tp->address -= offs; in post_process_probe_trace_point()
722 * Rename DWARF symbols to ELF symbols -- gcc sometimes optimizes functions
741 return -EINVAL; in post_process_offline_probe_trace_events()
745 ret = post_process_probe_trace_point(&tevs[i].point, in post_process_offline_probe_trace_events()
770 /* point.address is the address of point.symbol + point.offset */ in add_exec_to_probe_trace_events()
771 tevs[i].point.address -= stext; in add_exec_to_probe_trace_events()
772 tevs[i].point.module = strdup(exec); in add_exec_to_probe_trace_events()
773 if (!tevs[i].point.module) { in add_exec_to_probe_trace_events()
774 ret = -ENOMEM; in add_exec_to_probe_trace_events()
799 return -EINVAL; in post_process_module_probe_trace_events()
804 ret = post_process_probe_trace_point(&tevs[i].point, in post_process_module_probe_trace_events()
808 tevs[i].point.module = in post_process_module_probe_trace_events()
810 if (!tevs[i].point.module) { in post_process_module_probe_trace_events()
811 ret = -ENOMEM; in post_process_module_probe_trace_events()
842 return -EINVAL; in post_process_kernel_probe_trace_events()
846 if (!tevs[i].point.address) in post_process_kernel_probe_trace_events()
848 if (tevs[i].point.retprobe && !kretprobe_offset_is_supported()) in post_process_kernel_probe_trace_events()
855 if (kprobe_warn_out_range(tevs[i].point.symbol, in post_process_kernel_probe_trace_events()
856 map__objdump_2mem(map, tevs[i].point.address))) { in post_process_kernel_probe_trace_events()
860 tmp = strdup(reloc_sym->name); in post_process_kernel_probe_trace_events()
862 return -ENOMEM; in post_process_kernel_probe_trace_events()
865 if (!tevs[i].point.realname) in post_process_kernel_probe_trace_events()
866 tevs[i].point.realname = tevs[i].point.symbol; in post_process_kernel_probe_trace_events()
868 free(tevs[i].point.symbol); in post_process_kernel_probe_trace_events()
869 tevs[i].point.symbol = tmp; in post_process_kernel_probe_trace_events()
870 tevs[i].point.offset = tevs[i].point.address - in post_process_kernel_probe_trace_events()
871 (map__reloc(map) ? reloc_sym->unrelocated_addr : in post_process_kernel_probe_trace_events()
872 reloc_sym->addr); in post_process_kernel_probe_trace_events()
893 pev->nsi); in post_process_probe_trace_events()
918 * compiled by gcc with -fpatchable-function-entry option enabled. The in try_to_find_probe_trace_events()
923 if (pev->point.retprobe) in try_to_find_probe_trace_events()
926 dinfo = open_debuginfo(pev->target, pev->nsi, !need_dwarf); in try_to_find_probe_trace_events()
929 return -ENODATA; in try_to_find_probe_trace_events()
934 pr_debug("Try to find probe point from debuginfo.\n"); in try_to_find_probe_trace_events()
946 clear_perf_probe_point(&pev->point); in try_to_find_probe_trace_events()
947 memcpy(&pev->point, &tmp, sizeof(tmp)); in try_to_find_probe_trace_events()
954 pev->target, pev->uprobes, dinfo); in try_to_find_probe_trace_events()
965 if (ntevs == 0) { /* No error but failed to find probe point. */ in try_to_find_probe_trace_events()
966 char *probe_point = synthesize_perf_probe_point(&pev->point); in try_to_find_probe_trace_events()
967 pr_warning("Probe point '%s' not found.\n", probe_point); in try_to_find_probe_trace_events()
969 return -ENODEV; in try_to_find_probe_trace_events()
973 if (ntevs == -EBADF) in try_to_find_probe_trace_events()
974 pr_warning("Warning: No dwarf info found in the vmlinux - " in try_to_find_probe_trace_events()
1011 return -1; in __show_one_line()
1021 rv = -1; in _show_one_line()
1032 * Show line-range always requires debuginfo to find source file and
1051 return -ENOENT; in __show_line_range()
1059 if (dinfo->build_id) { in __show_line_range()
1060 build_id__init(&bid, dinfo->build_id, BUILD_ID_SIZE); in __show_line_range()
1064 if (ret == 0 || ret == -ENOENT) { in __show_line_range()
1066 return -ENOENT; in __show_line_range()
1073 tmp = lr->path; in __show_line_range()
1074 ret = find_source_path(tmp, sbuild_id, lr->comp_dir, &lr->path); in __show_line_range()
1077 if (tmp != lr->path) in __show_line_range()
1087 if (lr->function) in __show_line_range()
1088 fprintf(stdout, "<%s@%s:%d>\n", lr->function, lr->path, in __show_line_range()
1089 lr->start - lr->offset); in __show_line_range()
1091 fprintf(stdout, "<%s:%d>\n", lr->path, lr->start); in __show_line_range()
1093 fp = fopen(lr->path, "r"); in __show_line_range()
1095 pr_warning("Failed to open %s: %s\n", lr->path, in __show_line_range()
1097 return -errno; in __show_line_range()
1100 while (l < lr->start) { in __show_line_range()
1103 goto end; in __show_line_range()
1106 intlist__for_each_entry(ln, lr->line_list) { in __show_line_range()
1107 for (; ln->i > (unsigned long)l; l++) { in __show_line_range()
1108 ret = show_one_line(fp, l - lr->offset); in __show_line_range()
1110 goto end; in __show_line_range()
1112 ret = show_one_line_with_num(fp, l++ - lr->offset); in __show_line_range()
1114 goto end; in __show_line_range()
1117 if (lr->end == INT_MAX) in __show_line_range()
1118 lr->end = l + NR_ADDITIONAL_LINES; in __show_line_range()
1119 while (l <= lr->end) { in __show_line_range()
1120 ret = show_one_line_or_eof(fp, l++ - lr->offset); in __show_line_range()
1124 end: in __show_line_range()
1157 buf = synthesize_perf_probe_point(&pev->point); in show_available_vars_at()
1159 return -EINVAL; in show_available_vars_at()
1173 if (ret == 0 || ret == -ENOENT) { in show_available_vars_at()
1175 ret = -ENOENT; in show_available_vars_at()
1178 goto end; in show_available_vars_at()
1186 * A probe point might be converted to in show_available_vars_at()
1189 fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, in show_available_vars_at()
1190 vl->point.offset); in show_available_vars_at()
1191 zfree(&vl->point.symbol); in show_available_vars_at()
1193 if (vl->vars) { in show_available_vars_at()
1194 strlist__for_each_entry(node, vl->vars) { in show_available_vars_at()
1195 var = strchr(node->s, '\t') + 1; in show_available_vars_at()
1197 fprintf(stdout, "\t\t%s\n", node->s); in show_available_vars_at()
1201 strlist__delete(vl->vars); in show_available_vars_at()
1207 end: in show_available_vars_at()
1212 /* Show available variables on given probe point */
1219 ret = init_probe_symbol_maps(pevs->uprobes); in show_available_vars()
1223 dinfo = open_debuginfo(pevs->target, pevs->nsi, false); in show_available_vars()
1225 ret = -ENOENT; in show_available_vars()
1251 return -ENOSYS; in find_perf_probe_point_from_dwarf()
1258 pr_warning("Debuginfo-analysis is not supported.\n"); in try_to_find_probe_trace_events()
1259 return -ENOSYS; in try_to_find_probe_trace_events()
1270 pr_warning("Debuginfo-analysis is not supported.\n"); in show_line_range()
1271 return -ENOSYS; in show_line_range()
1278 pr_warning("Debuginfo-analysis is not supported.\n"); in show_available_vars()
1279 return -ENOSYS; in show_available_vars()
1285 zfree(&lr->function); in line_range__clear()
1286 zfree(&lr->file); in line_range__clear()
1287 zfree(&lr->path); in line_range__clear()
1288 zfree(&lr->comp_dir); in line_range__clear()
1289 intlist__delete(lr->line_list); in line_range__clear()
1295 lr->line_list = intlist__new(NULL); in line_range__init()
1296 if (!lr->line_list) in line_range__init()
1297 return -ENOMEM; in line_range__init()
1310 return -EINVAL; in parse_line_num()
1331 * SRC[:SLN[+NUM|-ELN]]
1332 * FNC[@SRC][:SLN[+NUM|-ELN]]
1340 return -ENOMEM; in parse_line_range_desc()
1342 lr->start = 0; in parse_line_range_desc()
1343 lr->end = INT_MAX; in parse_line_range_desc()
1349 err = parse_line_num(&range, &lr->start, "start line"); in parse_line_range_desc()
1353 if (*range == '+' || *range == '-') { in parse_line_range_desc()
1356 err = parse_line_num(&range, &lr->end, "end line"); in parse_line_range_desc()
1361 lr->end += lr->start; in parse_line_range_desc()
1365 * end of line should be equal to in parse_line_range_desc()
1368 lr->end--; in parse_line_range_desc()
1372 pr_debug("Line range is %d to %d\n", lr->start, lr->end); in parse_line_range_desc()
1374 err = -EINVAL; in parse_line_range_desc()
1375 if (lr->start > lr->end) { in parse_line_range_desc()
1377 " than end line.\n"); in parse_line_range_desc()
1389 lr->file = strdup(++file); in parse_line_range_desc()
1390 if (lr->file == NULL) { in parse_line_range_desc()
1391 err = -ENOMEM; in parse_line_range_desc()
1394 lr->function = name; in parse_line_range_desc()
1396 lr->file = name; in parse_line_range_desc()
1398 lr->function = name; in parse_line_range_desc()
1401 err = -EINVAL; in parse_line_range_desc()
1418 if (!pev->sdt && !is_c_func_name(*arg)) in parse_perf_probe_event_name()
1420 pev->group = strdup_esc(*arg); in parse_perf_probe_event_name()
1421 if (!pev->group) in parse_perf_probe_event_name()
1422 return -ENOMEM; in parse_perf_probe_event_name()
1425 pev->group = NULL; in parse_perf_probe_event_name()
1427 pev->event = strdup_esc(*arg); in parse_perf_probe_event_name()
1428 if (pev->event == NULL) in parse_perf_probe_event_name()
1429 return -ENOMEM; in parse_perf_probe_event_name()
1431 if (!pev->sdt && !is_c_func_name(pev->event)) { in parse_perf_probe_event_name()
1432 zfree(&pev->event); in parse_perf_probe_event_name()
1434 zfree(&pev->group); in parse_perf_probe_event_name()
1435 semantic_error("%s is bad for event name -it must " in parse_perf_probe_event_name()
1436 "follow C symbol-naming rule.\n", *arg); in parse_perf_probe_event_name()
1437 return -EINVAL; in parse_perf_probe_event_name()
1445 struct perf_probe_point *pp = &pev->point; in parse_perf_probe_point()
1458 return -EINVAL; in parse_perf_probe_point()
1461 pev->sdt = true; in parse_perf_probe_point()
1467 if (pev->sdt) { in parse_perf_probe_point()
1472 return -EINVAL; in parse_perf_probe_point()
1477 pev->target = build_id_cache__origname(tmp); in parse_perf_probe_point()
1480 pev->target = strdup_esc(ptr + 1); in parse_perf_probe_point()
1481 if (!pev->target) in parse_perf_probe_point()
1482 return -ENOMEM; in parse_perf_probe_point()
1487 if (asprintf(&pev->point.function, "%%%s", pev->event) < 0) in parse_perf_probe_point()
1488 ret = -errno; in parse_perf_probe_point()
1508 * - it does not include any of "+@%", in parse_perf_probe_point()
1509 * - it includes one of ":;", and in parse_perf_probe_point()
1510 * - it has a period '.' in the name. in parse_perf_probe_point()
1517 if (ptr && memchr(arg, '.', ptr - arg)) in parse_perf_probe_point()
1532 return -ENOMEM; in parse_perf_probe_point()
1536 pp->file = tmp; in parse_perf_probe_point()
1538 pp->function = tmp; in parse_perf_probe_point()
1541 * Keep pp->function even if this is absolute address, in parse_perf_probe_point()
1550 pp->abs_address = strtoull(pp->function, &tmp, 0); in parse_perf_probe_point()
1553 return -EINVAL; in parse_perf_probe_point()
1563 pp->lazy_line = strdup(arg); /* let leave escapes */ in parse_perf_probe_point()
1564 if (pp->lazy_line == NULL) in parse_perf_probe_point()
1565 return -ENOMEM; in parse_perf_probe_point()
1575 pp->line = strtoul(arg, &tmp, 0); in parse_perf_probe_point()
1577 semantic_error("There is non-digit char" in parse_perf_probe_point()
1579 return -EINVAL; in parse_perf_probe_point()
1583 pp->offset = strtoul(arg, &tmp, 0); in parse_perf_probe_point()
1585 semantic_error("There is non-digit character" in parse_perf_probe_point()
1587 return -EINVAL; in parse_perf_probe_point()
1591 if (pp->file) { in parse_perf_probe_point()
1593 return -EINVAL; in parse_perf_probe_point()
1595 pp->file = strdup_esc(arg); in parse_perf_probe_point()
1596 if (pp->file == NULL) in parse_perf_probe_point()
1597 return -ENOMEM; in parse_perf_probe_point()
1601 pp->retprobe = 1; in parse_perf_probe_point()
1604 return -ENOTSUP; in parse_perf_probe_point()
1610 return -ENOTSUP; in parse_perf_probe_point()
1616 if (pp->lazy_line && pp->line) { in parse_perf_probe_point()
1619 return -EINVAL; in parse_perf_probe_point()
1622 if (pp->lazy_line && pp->offset) { in parse_perf_probe_point()
1624 return -EINVAL; in parse_perf_probe_point()
1627 if (pp->line && pp->offset) { in parse_perf_probe_point()
1629 return -EINVAL; in parse_perf_probe_point()
1632 if (!pp->line && !pp->lazy_line && pp->file && !pp->function) { in parse_perf_probe_point()
1635 return -EINVAL; in parse_perf_probe_point()
1638 if (pp->offset && !pp->function) { in parse_perf_probe_point()
1640 return -EINVAL; in parse_perf_probe_point()
1643 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) { in parse_perf_probe_point()
1646 return -EINVAL; in parse_perf_probe_point()
1650 pp->function, pp->file, pp->line, pp->offset, pp->retprobe, in parse_perf_probe_point()
1651 pp->lazy_line); in parse_perf_probe_point()
1655 /* Parse perf-probe event argument */
1665 arg->name = strndup(str, tmp - str); in parse_perf_probe_arg()
1666 if (arg->name == NULL) in parse_perf_probe_arg()
1667 return -ENOMEM; in parse_perf_probe_arg()
1668 pr_debug("name:%s ", arg->name); in parse_perf_probe_arg()
1676 return -EINVAL; in parse_perf_probe_arg()
1679 arg->user_access = true; in parse_perf_probe_arg()
1686 arg->type = strdup(tmp + 1); in parse_perf_probe_arg()
1687 if (arg->type == NULL) in parse_perf_probe_arg()
1688 return -ENOMEM; in parse_perf_probe_arg()
1689 pr_debug("type:%s ", arg->type); in parse_perf_probe_arg()
1692 tmp = strpbrk(str, "-.["); in parse_perf_probe_arg()
1695 arg->var = strdup(str); in parse_perf_probe_arg()
1696 if (arg->var == NULL) in parse_perf_probe_arg()
1697 return -ENOMEM; in parse_perf_probe_arg()
1698 pr_debug("%s\n", arg->var); in parse_perf_probe_arg()
1703 arg->var = strndup(str, tmp - str); in parse_perf_probe_arg()
1704 if (arg->var == NULL) in parse_perf_probe_arg()
1705 return -ENOMEM; in parse_perf_probe_arg()
1706 goodname = arg->var; in parse_perf_probe_arg()
1707 pr_debug("%s, ", arg->var); in parse_perf_probe_arg()
1708 fieldp = &arg->field; in parse_perf_probe_arg()
1713 return -ENOMEM; in parse_perf_probe_arg()
1716 (*fieldp)->index = strtol(str + 1, &tmp, 0); in parse_perf_probe_arg()
1717 (*fieldp)->ref = true; in parse_perf_probe_arg()
1721 return -EINVAL; in parse_perf_probe_arg()
1729 (*fieldp)->ref = false; in parse_perf_probe_arg()
1732 (*fieldp)->ref = true; in parse_perf_probe_arg()
1736 return -EINVAL; in parse_perf_probe_arg()
1738 tmp = strpbrk(str, "-.["); in parse_perf_probe_arg()
1741 (*fieldp)->name = strndup(str, tmp - str); in parse_perf_probe_arg()
1742 if ((*fieldp)->name == NULL) in parse_perf_probe_arg()
1743 return -ENOMEM; in parse_perf_probe_arg()
1745 goodname = (*fieldp)->name; in parse_perf_probe_arg()
1746 pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref); in parse_perf_probe_arg()
1747 fieldp = &(*fieldp)->next; in parse_perf_probe_arg()
1750 (*fieldp)->name = strdup(str); in parse_perf_probe_arg()
1751 if ((*fieldp)->name == NULL) in parse_perf_probe_arg()
1752 return -ENOMEM; in parse_perf_probe_arg()
1754 goodname = (*fieldp)->name; in parse_perf_probe_arg()
1755 pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref); in parse_perf_probe_arg()
1758 if (!arg->name) { in parse_perf_probe_arg()
1759 arg->name = strdup(goodname); in parse_perf_probe_arg()
1760 if (arg->name == NULL) in parse_perf_probe_arg()
1761 return -ENOMEM; in parse_perf_probe_arg()
1766 /* Parse perf-probe event command */
1775 return -ENOMEM; in parse_perf_probe_command()
1777 if (argc - 1 > MAX_PROBE_ARGS) { in parse_perf_probe_command()
1778 semantic_error("Too many probe arguments (%d).\n", argc - 1); in parse_perf_probe_command()
1779 ret = -ERANGE; in parse_perf_probe_command()
1782 /* Parse probe point */ in parse_perf_probe_command()
1788 if (!pev->event && pev->point.function && pev->point.line in parse_perf_probe_command()
1789 && !pev->point.lazy_line && !pev->point.offset) { in parse_perf_probe_command()
1790 if (asprintf(&pev->event, "%s_L%d", pev->point.function, in parse_perf_probe_command()
1791 pev->point.line) < 0) { in parse_perf_probe_command()
1792 ret = -ENOMEM; in parse_perf_probe_command()
1798 pev->nargs = argc - 1; in parse_perf_probe_command()
1799 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs); in parse_perf_probe_command()
1800 if (pev->args == NULL) { in parse_perf_probe_command()
1801 ret = -ENOMEM; in parse_perf_probe_command()
1804 for (i = 0; i < pev->nargs && ret >= 0; i++) { in parse_perf_probe_command()
1805 ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]); in parse_perf_probe_command()
1807 is_c_varname(pev->args[i].var) && pev->point.retprobe) { in parse_perf_probe_command()
1810 ret = -EINVAL; in parse_perf_probe_command()
1824 for (i = 0; i < pev->nargs; i++) in perf_probe_with_var()
1825 if (is_c_varname(pev->args[i].var) || in perf_probe_with_var()
1826 !strcmp(pev->args[i].var, PROBE_ARG_PARAMS) || in perf_probe_with_var()
1827 !strcmp(pev->args[i].var, PROBE_ARG_VARS)) in perf_probe_with_var()
1835 if (pev->point.file || pev->point.line || pev->point.lazy_line) in perf_probe_event_need_dwarf()
1847 struct probe_trace_point *tp = &tev->point; in parse_probe_trace_command()
1858 return -ENOMEM; in parse_probe_trace_command()
1862 ret = -ERANGE; in parse_probe_trace_command()
1869 ret = -ENOMEM; in parse_probe_trace_command()
1877 ret = -EINVAL; in parse_probe_trace_command()
1881 tev->group = strdup(fmt2_str); in parse_probe_trace_command()
1882 tev->event = strdup(fmt3_str); in parse_probe_trace_command()
1883 if (tev->group == NULL || tev->event == NULL) { in parse_probe_trace_command()
1884 ret = -ENOMEM; in parse_probe_trace_command()
1887 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); in parse_probe_trace_command()
1889 tp->retprobe = (pr == 'r'); in parse_probe_trace_command()
1894 tp->module = strndup(argv[1], p - argv[1]); in parse_probe_trace_command()
1895 if (!tp->module) { in parse_probe_trace_command()
1896 ret = -ENOMEM; in parse_probe_trace_command()
1899 tev->uprobes = (tp->module[0] == '/'); in parse_probe_trace_command()
1909 * p:probe_libc/abs_0 /lib/libc-2.18.so:0x (null) arg1=%ax in parse_probe_trace_command()
1915 ret = -EINVAL; in parse_probe_trace_command()
1918 tp->address = 0; in parse_probe_trace_command()
1925 argc -= 1; in parse_probe_trace_command()
1927 tp->address = strtoull(fmt1_str, NULL, 0); in parse_probe_trace_command()
1929 /* Only the symbol-based probe has offset */ in parse_probe_trace_command()
1930 tp->symbol = strdup(fmt1_str); in parse_probe_trace_command()
1931 if (tp->symbol == NULL) { in parse_probe_trace_command()
1932 ret = -ENOMEM; in parse_probe_trace_command()
1937 tp->offset = 0; in parse_probe_trace_command()
1939 tp->offset = strtoul(fmt2_str, NULL, 10); in parse_probe_trace_command()
1942 if (tev->uprobes) { in parse_probe_trace_command()
1945 tp->ref_ctr_offset = strtoul(fmt2_str + 1, NULL, 0); in parse_probe_trace_command()
1948 tev->nargs = argc - 2; in parse_probe_trace_command()
1949 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); in parse_probe_trace_command()
1950 if (tev->args == NULL) { in parse_probe_trace_command()
1951 ret = -ENOMEM; in parse_probe_trace_command()
1954 for (i = 0; i < tev->nargs; i++) { in parse_probe_trace_command()
1960 tev->args[i].name = strdup(argv[i + 2]); in parse_probe_trace_command()
1962 tev->args[i].value = strdup(p); in parse_probe_trace_command()
1963 if (tev->args[i].name == NULL || tev->args[i].value == NULL) { in parse_probe_trace_command()
1964 ret = -ENOMEM; in parse_probe_trace_command()
1978 struct perf_probe_arg_field *field = pa->field; in synthesize_perf_probe_arg()
1986 if (pa->name && pa->var) in synthesize_perf_probe_arg()
1987 err = strbuf_addf(&buf, "%s=%s", pa->name, pa->var); in synthesize_perf_probe_arg()
1989 err = strbuf_addstr(&buf, pa->name ?: pa->var); in synthesize_perf_probe_arg()
1994 if (field->name[0] == '[') in synthesize_perf_probe_arg()
1995 err = strbuf_addstr(&buf, field->name); in synthesize_perf_probe_arg()
1997 err = strbuf_addf(&buf, "%s%s", field->ref ? "->" : ".", in synthesize_perf_probe_arg()
1998 field->name); in synthesize_perf_probe_arg()
1999 field = field->next; in synthesize_perf_probe_arg()
2004 if (pa->type) in synthesize_perf_probe_arg()
2005 if (strbuf_addf(&buf, ":%s", pa->type) < 0) in synthesize_perf_probe_arg()
2014 /* Compose only probe point (not argument) */
2024 if (pp->function) { in synthesize_perf_probe_point()
2025 if (strbuf_addstr(&buf, pp->function) < 0) in synthesize_perf_probe_point()
2027 if (pp->offset) in synthesize_perf_probe_point()
2028 err = strbuf_addf(&buf, "+%lu", pp->offset); in synthesize_perf_probe_point()
2029 else if (pp->line) in synthesize_perf_probe_point()
2030 err = strbuf_addf(&buf, ":%d", pp->line); in synthesize_perf_probe_point()
2031 else if (pp->retprobe) in synthesize_perf_probe_point()
2036 if (pp->file) { in synthesize_perf_probe_point()
2037 tmp = pp->file; in synthesize_perf_probe_point()
2040 tmp = strchr(pp->file + len - 30, '/'); in synthesize_perf_probe_point()
2041 tmp = tmp ? tmp + 1 : pp->file + len - 30; in synthesize_perf_probe_point()
2044 if (!err && !pp->function && pp->line) in synthesize_perf_probe_point()
2045 err = strbuf_addf(&buf, ":%d", pp->line); in synthesize_perf_probe_point()
2062 if (pev->event) in synthesize_perf_probe_command()
2063 if (strbuf_addf(&buf, "%s:%s=", pev->group ?: PERFPROBE_GROUP, in synthesize_perf_probe_command()
2064 pev->event) < 0) in synthesize_perf_probe_command()
2067 tmp = synthesize_perf_probe_point(&pev->point); in synthesize_perf_probe_command()
2074 for (i = 0; i < pev->nargs; i++) { in synthesize_perf_probe_command()
2075 tmp = synthesize_perf_probe_arg(pev->args + i); in synthesize_perf_probe_command()
2093 if (ref->next) { in __synthesize_probe_trace_arg_ref()
2094 depth = __synthesize_probe_trace_arg_ref(ref->next, buf, in __synthesize_probe_trace_arg_ref()
2099 if (ref->user_access) in __synthesize_probe_trace_arg_ref()
2100 err = strbuf_addf(buf, "%s%ld(", "+u", ref->offset); in __synthesize_probe_trace_arg_ref()
2102 err = strbuf_addf(buf, "%+ld(", ref->offset); in __synthesize_probe_trace_arg_ref()
2109 struct probe_trace_arg_ref *ref = arg->ref; in synthesize_probe_trace_arg()
2113 if (arg->name) in synthesize_probe_trace_arg()
2114 err = strbuf_addf(buf, " %s=", arg->name); in synthesize_probe_trace_arg()
2121 if (arg->value[0] == '@' && arg->ref) in synthesize_probe_trace_arg()
2122 ref = ref->next; in synthesize_probe_trace_arg()
2132 if (arg->value[0] == '@' && arg->ref) in synthesize_probe_trace_arg()
2133 err = strbuf_addf(buf, "%s%+ld", arg->value, arg->ref->offset); in synthesize_probe_trace_arg()
2135 err = strbuf_addstr(buf, arg->value); in synthesize_probe_trace_arg()
2138 while (!err && depth--) in synthesize_probe_trace_arg()
2142 if (!err && arg->type) in synthesize_probe_trace_arg()
2143 err = strbuf_addf(buf, ":%s", arg->type); in synthesize_probe_trace_arg()
2153 for (i = 0; i < tev->nargs && ret >= 0; i++) in synthesize_probe_trace_args()
2154 ret = synthesize_probe_trace_arg(&tev->args[i], buf); in synthesize_probe_trace_args()
2164 /* Uprobes must have tp->module */ in synthesize_uprobe_trace_def()
2165 if (!tp->module) in synthesize_uprobe_trace_def()
2166 return -EINVAL; in synthesize_uprobe_trace_def()
2168 * If tp->address == 0, then this point must be a in synthesize_uprobe_trace_def()
2171 * tp->symbol to "0x0". in synthesize_uprobe_trace_def()
2173 if (!tp->address && (!tp->symbol || strcmp(tp->symbol, "0x0"))) in synthesize_uprobe_trace_def()
2174 return -EINVAL; in synthesize_uprobe_trace_def()
2176 /* Use the tp->address for uprobes */ in synthesize_uprobe_trace_def()
2177 err = strbuf_addf(buf, "%s:0x%" PRIx64, tp->module, tp->address); in synthesize_uprobe_trace_def()
2179 if (err >= 0 && tp->ref_ctr_offset) { in synthesize_uprobe_trace_def()
2181 return -EINVAL; in synthesize_uprobe_trace_def()
2182 err = strbuf_addf(buf, "(0x%lx)", tp->ref_ctr_offset); in synthesize_uprobe_trace_def()
2190 if (!strncmp(tp->symbol, "0x", 2)) { in synthesize_kprobe_trace_def()
2192 return strbuf_addf(buf, "%s%s0x%" PRIx64, tp->module ?: "", in synthesize_kprobe_trace_def()
2193 tp->module ? ":" : "", tp->address); in synthesize_kprobe_trace_def()
2195 return strbuf_addf(buf, "%s%s%s+%lu", tp->module ?: "", in synthesize_kprobe_trace_def()
2196 tp->module ? ":" : "", tp->symbol, tp->offset); in synthesize_kprobe_trace_def()
2202 struct probe_trace_point *tp = &tev->point; in synthesize_probe_trace_command()
2210 if (strbuf_addf(&buf, "%c:%s/%s ", tp->retprobe ? 'r' : 'p', in synthesize_probe_trace_command()
2211 tev->group, tev->event) < 0) in synthesize_probe_trace_command()
2214 if (tev->uprobes) in synthesize_probe_trace_command()
2235 u64 addr = tp->address; in find_perf_probe_point_from_map()
2236 int ret = -ENOENT; in find_perf_probe_point_from_map()
2239 map = dso__new_map(tp->module); in find_perf_probe_point_from_map()
2244 if (tp->symbol && !addr) { in find_perf_probe_point_from_map()
2245 if (kernel_get_symbol_address_by_name(tp->symbol, in find_perf_probe_point_from_map()
2250 addr += tp->offset; in find_perf_probe_point_from_map()
2258 pp->retprobe = tp->retprobe; in find_perf_probe_point_from_map()
2259 pp->offset = addr - map__unmap_ip(map, sym->start); in find_perf_probe_point_from_map()
2260 pp->function = strdup(sym->name); in find_perf_probe_point_from_map()
2261 ret = pp->function ? 0 : -ENOMEM; in find_perf_probe_point_from_map()
2285 pr_debug("Failed to find probe point from both of dwarf and map.\n"); in convert_to_perf_probe_point()
2287 if (tp->symbol) { in convert_to_perf_probe_point()
2288 pp->function = strdup(tp->symbol); in convert_to_perf_probe_point()
2289 pp->offset = tp->offset; in convert_to_perf_probe_point()
2291 ret = e_snprintf(buf, 128, "0x%" PRIx64, tp->address); in convert_to_perf_probe_point()
2294 pp->function = strdup(buf); in convert_to_perf_probe_point()
2295 pp->offset = 0; in convert_to_perf_probe_point()
2297 if (pp->function == NULL) in convert_to_perf_probe_point()
2298 return -ENOMEM; in convert_to_perf_probe_point()
2300 pp->retprobe = tp->retprobe; in convert_to_perf_probe_point()
2312 pev->event = strdup(tev->event); in convert_to_perf_probe_event()
2313 pev->group = strdup(tev->group); in convert_to_perf_probe_event()
2314 if (pev->event == NULL || pev->group == NULL) in convert_to_perf_probe_event()
2315 return -ENOMEM; in convert_to_perf_probe_event()
2318 ret = convert_to_perf_probe_point(&tev->point, &pev->point, is_kprobe); in convert_to_perf_probe_event()
2323 pev->nargs = tev->nargs; in convert_to_perf_probe_event()
2324 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs); in convert_to_perf_probe_event()
2325 if (pev->args == NULL) in convert_to_perf_probe_event()
2326 return -ENOMEM; in convert_to_perf_probe_event()
2327 for (i = 0; i < tev->nargs && ret >= 0; i++) { in convert_to_perf_probe_event()
2328 if (tev->args[i].name) in convert_to_perf_probe_event()
2329 pev->args[i].name = strdup(tev->args[i].name); in convert_to_perf_probe_event()
2333 ret = synthesize_probe_trace_arg(&tev->args[i], &buf); in convert_to_perf_probe_event()
2334 pev->args[i].name = strbuf_detach(&buf, NULL); in convert_to_perf_probe_event()
2336 if (pev->args[i].name == NULL && ret >= 0) in convert_to_perf_probe_event()
2337 ret = -ENOMEM; in convert_to_perf_probe_event()
2351 zfree(&pev->event); in clear_perf_probe_event()
2352 zfree(&pev->group); in clear_perf_probe_event()
2353 zfree(&pev->target); in clear_perf_probe_event()
2354 clear_perf_probe_point(&pev->point); in clear_perf_probe_event()
2356 for (i = 0; i < pev->nargs; i++) { in clear_perf_probe_event()
2357 zfree(&pev->args[i].name); in clear_perf_probe_event()
2358 zfree(&pev->args[i].var); in clear_perf_probe_event()
2359 zfree(&pev->args[i].type); in clear_perf_probe_event()
2360 field = pev->args[i].field; in clear_perf_probe_event()
2362 next = field->next; in clear_perf_probe_event()
2363 zfree(&field->name); in clear_perf_probe_event()
2368 pev->nargs = 0; in clear_perf_probe_event()
2369 zfree(&pev->args); in clear_perf_probe_event()
2378 dst->file = strdup_or_goto(src->file, out_err); in perf_probe_point__copy()
2379 dst->function = strdup_or_goto(src->function, out_err); in perf_probe_point__copy()
2380 dst->lazy_line = strdup_or_goto(src->lazy_line, out_err); in perf_probe_point__copy()
2381 dst->line = src->line; in perf_probe_point__copy()
2382 dst->retprobe = src->retprobe; in perf_probe_point__copy()
2383 dst->offset = src->offset; in perf_probe_point__copy()
2388 return -ENOMEM; in perf_probe_point__copy()
2396 dst->name = strdup_or_goto(src->name, out_err); in perf_probe_arg__copy()
2397 dst->var = strdup_or_goto(src->var, out_err); in perf_probe_arg__copy()
2398 dst->type = strdup_or_goto(src->type, out_err); in perf_probe_arg__copy()
2400 field = src->field; in perf_probe_arg__copy()
2401 ppfield = &(dst->field); in perf_probe_arg__copy()
2406 (*ppfield)->name = strdup_or_goto(field->name, out_err); in perf_probe_arg__copy()
2407 (*ppfield)->index = field->index; in perf_probe_arg__copy()
2408 (*ppfield)->ref = field->ref; in perf_probe_arg__copy()
2409 field = field->next; in perf_probe_arg__copy()
2410 ppfield = &((*ppfield)->next); in perf_probe_arg__copy()
2414 return -ENOMEM; in perf_probe_arg__copy()
2422 dst->event = strdup_or_goto(src->event, out_err); in perf_probe_event__copy()
2423 dst->group = strdup_or_goto(src->group, out_err); in perf_probe_event__copy()
2424 dst->target = strdup_or_goto(src->target, out_err); in perf_probe_event__copy()
2425 dst->uprobes = src->uprobes; in perf_probe_event__copy()
2427 if (perf_probe_point__copy(&dst->point, &src->point) < 0) in perf_probe_event__copy()
2430 dst->args = zalloc(sizeof(struct perf_probe_arg) * src->nargs); in perf_probe_event__copy()
2431 if (!dst->args) in perf_probe_event__copy()
2433 dst->nargs = src->nargs; in perf_probe_event__copy()
2435 for (i = 0; i < src->nargs; i++) in perf_probe_event__copy()
2436 if (perf_probe_arg__copy(&dst->args[i], &src->args[i]) < 0) in perf_probe_event__copy()
2442 return -ENOMEM; in perf_probe_event__copy()
2450 zfree(&tev->event); in clear_probe_trace_event()
2451 zfree(&tev->group); in clear_probe_trace_event()
2452 zfree(&tev->point.symbol); in clear_probe_trace_event()
2453 zfree(&tev->point.realname); in clear_probe_trace_event()
2454 zfree(&tev->point.module); in clear_probe_trace_event()
2455 for (i = 0; i < tev->nargs; i++) { in clear_probe_trace_event()
2456 zfree(&tev->args[i].name); in clear_probe_trace_event()
2457 zfree(&tev->args[i].value); in clear_probe_trace_event()
2458 zfree(&tev->args[i].type); in clear_probe_trace_event()
2459 ref = tev->args[i].ref; in clear_probe_trace_event()
2461 next = ref->next; in clear_probe_trace_event()
2466 zfree(&tev->args); in clear_probe_trace_event()
2467 tev->nargs = 0; in clear_probe_trace_event()
2473 u64 end; member
2484 list_del_init(&node->list); in kprobe_blacklist__delete()
2485 zfree(&node->symbol); in kprobe_blacklist__delete()
2499 return -ENOTSUP; in kprobe_blacklist__load()
2507 return -errno; in kprobe_blacklist__load()
2513 ret = -ENOMEM; in kprobe_blacklist__load()
2516 INIT_LIST_HEAD(&node->list); in kprobe_blacklist__load()
2517 list_add_tail(&node->list, blacklist); in kprobe_blacklist__load()
2518 if (sscanf(buf, "0x%" PRIx64 "-0x%" PRIx64, &node->start, &node->end) != 2) { in kprobe_blacklist__load()
2519 ret = -EINVAL; in kprobe_blacklist__load()
2525 if (p[strlen(p) - 1] == '\n') in kprobe_blacklist__load()
2526 p[strlen(p) - 1] = '\0'; in kprobe_blacklist__load()
2529 node->symbol = strdup(p); in kprobe_blacklist__load()
2530 if (!node->symbol) { in kprobe_blacklist__load()
2531 ret = -ENOMEM; in kprobe_blacklist__load()
2534 pr_debug2("Blacklist: 0x%" PRIx64 "-0x%" PRIx64 ", %s\n", in kprobe_blacklist__load()
2535 node->start, node->end, node->symbol); in kprobe_blacklist__load()
2551 if (node->start <= address && address < node->end) in kprobe_blacklist__find_by_address()
2588 return -errno; in perf_probe_event__sprintf()
2589 ret = strbuf_addf(result, " %-20s (on ", buf); in perf_probe_event__sprintf()
2594 /* Synthesize only event probe point */ in perf_probe_event__sprintf()
2595 buf = synthesize_perf_probe_point(&pev->point); in perf_probe_event__sprintf()
2597 return -ENOMEM; in perf_probe_event__sprintf()
2604 if (!ret && pev->nargs > 0) { in perf_probe_event__sprintf()
2606 for (i = 0; !ret && i < pev->nargs; i++) { in perf_probe_event__sprintf()
2607 buf = synthesize_perf_probe_arg(&pev->args[i]); in perf_probe_event__sprintf()
2609 return -ENOMEM; in perf_probe_event__sprintf()
2646 if (strfilter__compare(filter, tev->event)) in filter_probe_trace_event()
2650 if (e_snprintf(tmp, 128, "%s:%s", tev->group, tev->event) < 0) in filter_probe_trace_event()
2669 return -ENOMEM; in __show_perf_probe_events()
2672 ret = parse_probe_trace_command(ent->s, &tev); in __show_perf_probe_events()
2681 &pev, tev.point.module, in __show_perf_probe_events()
2697 /* List up current perf-probe events */
2739 return -ENOMEM; in get_new_event_name()
2757 " Hint: Remove existing event by 'perf probe -d'\n" in get_new_event_name()
2758 " or force duplicates by 'perf probe -f'\n" in get_new_event_name()
2761 ret = -EEXIST; in get_new_event_name()
2777 ret = -ERANGE; in get_new_event_name()
2787 ret = -EINVAL; in get_new_event_name()
2798 struct probe_trace_point *tp = &tev->point; in warn_uprobe_event_compat()
2800 if (tp->ref_ctr_offset && !uprobe_ref_ctr_is_supported()) { in warn_uprobe_event_compat()
2803 tev->group, tev->event); in warn_uprobe_event_compat()
2807 if (!tev->uprobes || tev->nargs == 0 || !buf) in warn_uprobe_event_compat()
2810 for (i = 0; i < tev->nargs; i++) { in warn_uprobe_event_compat()
2811 if (strchr(tev->args[i].value, '@')) { in warn_uprobe_event_compat()
2813 tev->args[i].value); in warn_uprobe_event_compat()
2816 if (strglobmatch(tev->args[i].value, "[$+-]*")) { in warn_uprobe_event_compat()
2818 tev->args[i].value); in warn_uprobe_event_compat()
2837 if (pev->event && !pev->sdt) in probe_trace_event__set_name()
2838 event = pev->event; in probe_trace_event__set_name()
2839 else if (tev->event) in probe_trace_event__set_name()
2840 event = tev->event; in probe_trace_event__set_name()
2842 /* Or generate new one from probe point */ in probe_trace_event__set_name()
2843 if (pev->point.function && in probe_trace_event__set_name()
2844 (strncmp(pev->point.function, "0x", 2) != 0) && in probe_trace_event__set_name()
2845 !strisglob(pev->point.function)) in probe_trace_event__set_name()
2846 event = pev->point.function; in probe_trace_event__set_name()
2848 event = tev->point.realname; in probe_trace_event__set_name()
2850 if (pev->group && !pev->sdt) in probe_trace_event__set_name()
2851 group = pev->group; in probe_trace_event__set_name()
2852 else if (tev->group) in probe_trace_event__set_name()
2853 group = tev->group; in probe_trace_event__set_name()
2859 tev->point.retprobe, allow_suffix); in probe_trace_event__set_name()
2865 tev->event = strdup(event); in probe_trace_event__set_name()
2866 tev->group = strdup(group); in probe_trace_event__set_name()
2867 if (tev->event == NULL || tev->group == NULL) in probe_trace_event__set_name()
2868 return -ENOMEM; in probe_trace_event__set_name()
2894 return -ENOMEM; in __open_probe_file_and_namelist()
2903 int i, fd[2] = {-1, -1}, up, ret; in __add_probe_trace_events()
2909 up = pev->uprobes ? 1 : 0; in __add_probe_trace_events()
2917 up = tev->uprobes ? 1 : 0; in __add_probe_trace_events()
2918 if (fd[up] == -1) { /* Open the kprobe/uprobe_events */ in __add_probe_trace_events()
2925 if (!tev->point.symbol && !pev->uprobes) in __add_probe_trace_events()
2934 nsinfo__mountns_enter(pev->nsi, &nsc); in __add_probe_trace_events()
2948 if (ret == -EINVAL && pev->uprobes) in __add_probe_trace_events()
2951 cache = probe_cache__new(pev->target, pev->nsi); in __add_probe_trace_events()
2979 return -EACCES; /* Possible permission error to load symbols */ in find_probe_functions()
2986 norm = arch__normalize_symbol_name(sym->name); in find_probe_functions()
2994 buf = strndup(norm, ver - norm); in find_probe_functions()
2996 return -ENOMEM; in find_probe_functions()
3004 syms[found - 1] = sym; in find_probe_functions()
3041 struct perf_probe_point *pp = &pev->point; in find_probe_trace_events_from_map()
3047 map = get_target_map(pev->target, pev->nsi, pev->uprobes); in find_probe_trace_events_from_map()
3049 ret = -EINVAL; in find_probe_trace_events_from_map()
3055 ret = -ENOMEM; in find_probe_trace_events_from_map()
3063 num_matched_functions = find_probe_functions(map, pp->function, syms); in find_probe_trace_events_from_map()
3065 if (num_matched_functions == -EACCES) { in find_probe_trace_events_from_map()
3067 pev->target ?: "/proc/kallsyms"); in find_probe_trace_events_from_map()
3068 if (pev->target) in find_probe_trace_events_from_map()
3073 pr_err("Failed to find symbol %s in %s\n", pp->function, in find_probe_trace_events_from_map()
3074 pev->target ? : "kernel"); in find_probe_trace_events_from_map()
3075 ret = -ENOENT; in find_probe_trace_events_from_map()
3079 pev->target ? : "kernel"); in find_probe_trace_events_from_map()
3080 ret = -E2BIG; in find_probe_trace_events_from_map()
3085 if (!pev->uprobes && !pev->target && in find_probe_trace_events_from_map()
3086 (!pp->retprobe || kretprobe_offset_is_supported())) { in find_probe_trace_events_from_map()
3093 ret = -EINVAL; in find_probe_trace_events_from_map()
3098 /* Setup result trace-probe-events */ in find_probe_trace_events_from_map()
3101 ret = -ENOMEM; in find_probe_trace_events_from_map()
3110 if (sym->type != STT_FUNC) in find_probe_trace_events_from_map()
3115 if (sym->start == syms[i]->start) { in find_probe_trace_events_from_map()
3117 sym->name, sym->start); in find_probe_trace_events_from_map()
3124 tp = &tev->point; in find_probe_trace_events_from_map()
3131 if (pp->offset > sym->end - sym->start) { in find_probe_trace_events_from_map()
3133 pp->offset, sym->name); in find_probe_trace_events_from_map()
3134 ret = -ENOENT; in find_probe_trace_events_from_map()
3137 /* Add one probe point */ in find_probe_trace_events_from_map()
3138 tp->address = map__unmap_ip(map, sym->start) + pp->offset; in find_probe_trace_events_from_map()
3141 if (!pev->uprobes && !pev->target && in find_probe_trace_events_from_map()
3142 kprobe_warn_out_range(sym->name, tp->address)) { in find_probe_trace_events_from_map()
3143 tp->symbol = NULL; /* Skip it */ in find_probe_trace_events_from_map()
3146 tp->symbol = strdup_or_goto(reloc_sym->name, nomem_out); in find_probe_trace_events_from_map()
3147 tp->offset = tp->address - reloc_sym->addr; in find_probe_trace_events_from_map()
3149 tp->symbol = strdup_or_goto(sym->name, nomem_out); in find_probe_trace_events_from_map()
3150 tp->offset = pp->offset; in find_probe_trace_events_from_map()
3152 tp->realname = strdup_or_goto(sym->name, nomem_out); in find_probe_trace_events_from_map()
3154 tp->retprobe = pp->retprobe; in find_probe_trace_events_from_map()
3155 if (pev->target) { in find_probe_trace_events_from_map()
3156 if (pev->uprobes) { in find_probe_trace_events_from_map()
3157 tev->point.module = strdup_or_goto(pev->target, in find_probe_trace_events_from_map()
3160 mod_name = find_module_name(pev->target); in find_probe_trace_events_from_map()
3161 tev->point.module = in find_probe_trace_events_from_map()
3162 strdup(mod_name ? mod_name : pev->target); in find_probe_trace_events_from_map()
3164 if (!tev->point.module) in find_probe_trace_events_from_map()
3168 tev->uprobes = pev->uprobes; in find_probe_trace_events_from_map()
3169 tev->nargs = pev->nargs; in find_probe_trace_events_from_map()
3170 if (tev->nargs) { in find_probe_trace_events_from_map()
3171 tev->args = zalloc(sizeof(struct probe_trace_arg) * in find_probe_trace_events_from_map()
3172 tev->nargs); in find_probe_trace_events_from_map()
3173 if (tev->args == NULL) in find_probe_trace_events_from_map()
3176 for (i = 0; i < tev->nargs; i++) { in find_probe_trace_events_from_map()
3177 if (pev->args[i].name) in find_probe_trace_events_from_map()
3178 tev->args[i].name = in find_probe_trace_events_from_map()
3179 strdup_or_goto(pev->args[i].name, in find_probe_trace_events_from_map()
3182 tev->args[i].value = strdup_or_goto(pev->args[i].var, in find_probe_trace_events_from_map()
3184 if (pev->args[i].type) in find_probe_trace_events_from_map()
3185 tev->args[i].type = in find_probe_trace_events_from_map()
3186 strdup_or_goto(pev->args[i].type, in find_probe_trace_events_from_map()
3192 ret = -ENOENT; in find_probe_trace_events_from_map()
3202 ret = -ENOMEM; in find_probe_trace_events_from_map()
3212 struct perf_probe_point *pp = &pev->point; in try_to_find_absolute_address()
3217 if (!(pev->point.function && !strncmp(pev->point.function, "0x", 2))) in try_to_find_absolute_address()
3218 return -EINVAL; in try_to_find_absolute_address()
3220 return -EINVAL; in try_to_find_absolute_address()
3230 return -ENOMEM; in try_to_find_absolute_address()
3233 tp = &tev->point; in try_to_find_absolute_address()
3236 * Don't use tp->offset, use address directly, because in try_to_find_absolute_address()
3240 tp->address = pev->point.abs_address; in try_to_find_absolute_address()
3241 tp->retprobe = pp->retprobe; in try_to_find_absolute_address()
3242 tev->uprobes = pev->uprobes; in try_to_find_absolute_address()
3244 err = -ENOMEM; in try_to_find_absolute_address()
3250 if (asprintf(&tp->symbol, "0x%" PRIx64, tp->address) < 0) in try_to_find_absolute_address()
3254 if ((!tev->uprobes) && in try_to_find_absolute_address()
3255 (kprobe_warn_out_range(tev->point.symbol, in try_to_find_absolute_address()
3256 tev->point.address))) { in try_to_find_absolute_address()
3257 err = -EACCES; in try_to_find_absolute_address()
3261 if (asprintf(&tp->realname, "abs_%" PRIx64, tp->address) < 0) in try_to_find_absolute_address()
3264 if (pev->target) { in try_to_find_absolute_address()
3265 tp->module = strdup(pev->target); in try_to_find_absolute_address()
3266 if (!tp->module) in try_to_find_absolute_address()
3270 if (tev->group) { in try_to_find_absolute_address()
3271 tev->group = strdup(pev->group); in try_to_find_absolute_address()
3272 if (!tev->group) in try_to_find_absolute_address()
3276 if (pev->event) { in try_to_find_absolute_address()
3277 tev->event = strdup(pev->event); in try_to_find_absolute_address()
3278 if (!tev->event) in try_to_find_absolute_address()
3282 tev->nargs = pev->nargs; in try_to_find_absolute_address()
3283 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); in try_to_find_absolute_address()
3284 if (!tev->args) in try_to_find_absolute_address()
3287 for (i = 0; i < tev->nargs; i++) in try_to_find_absolute_address()
3288 copy_to_probe_trace_arg(&tev->args[i], &pev->args[i]); in try_to_find_absolute_address()
3326 ret = -E2BIG; in concat_probe_trace_events()
3332 ret = -ENOMEM; in concat_probe_trace_events()
3360 cache = probe_cache__new(target, pev->nsi); in find_cached_events()
3367 if (!entry->pev.event || !entry->pev.group) in find_cached_events()
3369 if ((!pev->group || strglobmatch(entry->pev.group, pev->group)) && in find_cached_events()
3370 strglobmatch(entry->pev.event, pev->event)) { in find_cached_events()
3386 pev->uprobes = true; in find_cached_events()
3406 ret = -errno; in find_cached_events_all()
3413 pathname = build_id_cache__origname(nd->s); in find_cached_events_all()
3443 if (pev->sdt) { in find_probe_trace_events_from_cache()
3445 if (!pev->target) in find_probe_trace_events_from_cache()
3448 return find_cached_events(pev, tevs, pev->target); in find_probe_trace_events_from_cache()
3450 cache = probe_cache__new(pev->target, pev->nsi); in find_probe_trace_events_from_cache()
3457 ret = pev->sdt ? -ENOENT : 0; in find_probe_trace_events_from_cache()
3461 ret = strlist__nr_entries(entry->tevlist); in find_probe_trace_events_from_cache()
3464 pev->target ? : "kernel"); in find_probe_trace_events_from_cache()
3465 ret = -E2BIG; in find_probe_trace_events_from_cache()
3471 ret = -ENOMEM; in find_probe_trace_events_from_cache()
3476 strlist__for_each_entry(node, entry->tevlist) { in find_probe_trace_events_from_cache()
3478 ret = parse_probe_trace_command(node->s, tev); in find_probe_trace_events_from_cache()
3482 tev->uprobes = pev->uprobes; in find_probe_trace_events_from_cache()
3496 if (!pev->group && !pev->sdt) { in convert_to_probe_trace_events()
3498 if (!pev->uprobes) { in convert_to_probe_trace_events()
3499 pev->group = strdup(PERFPROBE_GROUP); in convert_to_probe_trace_events()
3500 ret = pev->group ? 0 : -ENOMEM; in convert_to_probe_trace_events()
3502 ret = convert_exec_to_group(pev->target, &pev->group); in convert_to_probe_trace_events()
3515 if (ret > 0 || pev->sdt) /* SDT can be found only in the cache */ in convert_to_probe_trace_events()
3516 return ret == 0 ? -ENOENT : ret; /* Found in probe cache */ in convert_to_probe_trace_events()
3553 return -EINVAL; in show_probe_trace_event()
3571 return -ENOMEM; in show_probe_trace_events()
3575 for (i = 0; i < pev->ntevs && !ret; i++) { in show_probe_trace_events()
3576 tev = &pev->tevs[i]; in show_probe_trace_events()
3578 if (!tev->point.symbol && !pev->uprobes) in show_probe_trace_events()
3595 struct probe_trace_point *tp = &tev->point; in show_bootconfig_event()
3601 return -ENOMEM; in show_bootconfig_event()
3627 return -ENOMEM; in show_bootconfig_events()
3631 if (pev->group && strcmp(pev->group, "probe")) in show_bootconfig_events()
3632 pr_warning("WARN: Group name %s is ignored\n", pev->group); in show_bootconfig_events()
3633 if (pev->uprobes) { in show_bootconfig_events()
3635 ret = -EINVAL; in show_bootconfig_events()
3638 for (i = 0; i < pev->ntevs && !ret; i++) { in show_bootconfig_events()
3639 tev = &pev->tevs[i]; in show_bootconfig_events()
3641 if (!tev->point.symbol && !pev->uprobes) in show_bootconfig_events()
3650 if (!cur_name || strcmp(cur_name, tev->event)) { in show_bootconfig_events()
3652 cur_name ? "\n" : "", tev->event); in show_bootconfig_events()
3653 cur_name = tev->event; in show_bootconfig_events()
3692 nsinfo__zput(pev->nsi); in cleanup_perf_probe_events()
3701 ret = init_probe_symbol_maps(pevs->uprobes); in add_perf_probe_events()
3717 int ret, ret2, ufd = -1, kfd = -1; in del_perf_probe_events()
3721 return -EINVAL; in del_perf_probe_events()
3729 if (ret < 0 && ret != -ENOENT) in del_perf_probe_events()
3733 if (ret2 < 0 && ret2 != -ENOENT) { in del_perf_probe_events()
3765 return -EINVAL; in show_available_funcs()
3770 if (ret == -2) { in show_available_funcs()
3778 goto end; in show_available_funcs()
3786 for (size_t i = 0; i < dso->symbol_names_len; i++) { in show_available_funcs()
3787 struct symbol *pos = dso->symbol_names[i]; in show_available_funcs()
3789 if (strfilter__compare(_filter, pos->name)) in show_available_funcs()
3790 printf("%s\n", pos->name); in show_available_funcs()
3792 end: in show_available_funcs()
3802 tvar->value = strdup(pvar->var); in copy_to_probe_trace_arg()
3803 if (tvar->value == NULL) in copy_to_probe_trace_arg()
3804 return -ENOMEM; in copy_to_probe_trace_arg()
3805 if (pvar->type) { in copy_to_probe_trace_arg()
3806 tvar->type = strdup(pvar->type); in copy_to_probe_trace_arg()
3807 if (tvar->type == NULL) in copy_to_probe_trace_arg()
3808 return -ENOMEM; in copy_to_probe_trace_arg()
3810 if (pvar->name) { in copy_to_probe_trace_arg()
3811 tvar->name = strdup(pvar->name); in copy_to_probe_trace_arg()
3812 if (tvar->name == NULL) in copy_to_probe_trace_arg()
3813 return -ENOMEM; in copy_to_probe_trace_arg()
3815 tvar->name = NULL; in copy_to_probe_trace_arg()