aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-event.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r--tools/perf/util/probe-event.c85
1 files changed, 61 insertions, 24 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index b7aaf9b2294d..e1dbc9821617 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1325,27 +1325,30 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
1325{ 1325{
1326 char *ptr; 1326 char *ptr;
1327 1327
1328 ptr = strchr(*arg, ':'); 1328 ptr = strpbrk_esc(*arg, ":");
1329 if (ptr) { 1329 if (ptr) {
1330 *ptr = '\0'; 1330 *ptr = '\0';
1331 if (!pev->sdt && !is_c_func_name(*arg)) 1331 if (!pev->sdt && !is_c_func_name(*arg))
1332 goto ng_name; 1332 goto ng_name;
1333 pev->group = strdup(*arg); 1333 pev->group = strdup_esc(*arg);
1334 if (!pev->group) 1334 if (!pev->group)
1335 return -ENOMEM; 1335 return -ENOMEM;
1336 *arg = ptr + 1; 1336 *arg = ptr + 1;
1337 } else 1337 } else
1338 pev->group = NULL; 1338 pev->group = NULL;
1339 if (!pev->sdt && !is_c_func_name(*arg)) { 1339
1340 pev->event = strdup_esc(*arg);
1341 if (pev->event == NULL)
1342 return -ENOMEM;
1343
1344 if (!pev->sdt && !is_c_func_name(pev->event)) {
1345 zfree(&pev->event);
1340ng_name: 1346ng_name:
1347 zfree(&pev->group);
1341 semantic_error("%s is bad for event name -it must " 1348 semantic_error("%s is bad for event name -it must "
1342 "follow C symbol-naming rule.\n", *arg); 1349 "follow C symbol-naming rule.\n", *arg);
1343 return -EINVAL; 1350 return -EINVAL;
1344 } 1351 }
1345 pev->event = strdup(*arg);
1346 if (pev->event == NULL)
1347 return -ENOMEM;
1348
1349 return 0; 1352 return 0;
1350} 1353}
1351 1354
@@ -1373,7 +1376,7 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1373 arg++; 1376 arg++;
1374 } 1377 }
1375 1378
1376 ptr = strpbrk(arg, ";=@+%"); 1379 ptr = strpbrk_esc(arg, ";=@+%");
1377 if (pev->sdt) { 1380 if (pev->sdt) {
1378 if (ptr) { 1381 if (ptr) {
1379 if (*ptr != '@') { 1382 if (*ptr != '@') {
@@ -1387,7 +1390,7 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1387 pev->target = build_id_cache__origname(tmp); 1390 pev->target = build_id_cache__origname(tmp);
1388 free(tmp); 1391 free(tmp);
1389 } else 1392 } else
1390 pev->target = strdup(ptr + 1); 1393 pev->target = strdup_esc(ptr + 1);
1391 if (!pev->target) 1394 if (!pev->target)
1392 return -ENOMEM; 1395 return -ENOMEM;
1393 *ptr = '\0'; 1396 *ptr = '\0';
@@ -1421,13 +1424,14 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1421 * 1424 *
1422 * Otherwise, we consider arg to be a function specification. 1425 * Otherwise, we consider arg to be a function specification.
1423 */ 1426 */
1424 if (!strpbrk(arg, "+@%") && (ptr = strpbrk(arg, ";:")) != NULL) { 1427 if (!strpbrk_esc(arg, "+@%")) {
1428 ptr = strpbrk_esc(arg, ";:");
1425 /* This is a file spec if it includes a '.' before ; or : */ 1429 /* This is a file spec if it includes a '.' before ; or : */
1426 if (memchr(arg, '.', ptr - arg)) 1430 if (ptr && memchr(arg, '.', ptr - arg))
1427 file_spec = true; 1431 file_spec = true;
1428 } 1432 }
1429 1433
1430 ptr = strpbrk(arg, ";:+@%"); 1434 ptr = strpbrk_esc(arg, ";:+@%");
1431 if (ptr) { 1435 if (ptr) {
1432 nc = *ptr; 1436 nc = *ptr;
1433 *ptr++ = '\0'; 1437 *ptr++ = '\0';
@@ -1436,7 +1440,7 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1436 if (arg[0] == '\0') 1440 if (arg[0] == '\0')
1437 tmp = NULL; 1441 tmp = NULL;
1438 else { 1442 else {
1439 tmp = strdup(arg); 1443 tmp = strdup_esc(arg);
1440 if (tmp == NULL) 1444 if (tmp == NULL)
1441 return -ENOMEM; 1445 return -ENOMEM;
1442 } 1446 }
@@ -1469,12 +1473,12 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1469 arg = ptr; 1473 arg = ptr;
1470 c = nc; 1474 c = nc;
1471 if (c == ';') { /* Lazy pattern must be the last part */ 1475 if (c == ';') { /* Lazy pattern must be the last part */
1472 pp->lazy_line = strdup(arg); 1476 pp->lazy_line = strdup(arg); /* let leave escapes */
1473 if (pp->lazy_line == NULL) 1477 if (pp->lazy_line == NULL)
1474 return -ENOMEM; 1478 return -ENOMEM;
1475 break; 1479 break;
1476 } 1480 }
1477 ptr = strpbrk(arg, ";:+@%"); 1481 ptr = strpbrk_esc(arg, ";:+@%");
1478 if (ptr) { 1482 if (ptr) {
1479 nc = *ptr; 1483 nc = *ptr;
1480 *ptr++ = '\0'; 1484 *ptr++ = '\0';
@@ -1501,7 +1505,7 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1501 semantic_error("SRC@SRC is not allowed.\n"); 1505 semantic_error("SRC@SRC is not allowed.\n");
1502 return -EINVAL; 1506 return -EINVAL;
1503 } 1507 }
1504 pp->file = strdup(arg); 1508 pp->file = strdup_esc(arg);
1505 if (pp->file == NULL) 1509 if (pp->file == NULL)
1506 return -ENOMEM; 1510 return -ENOMEM;
1507 break; 1511 break;
@@ -2573,7 +2577,8 @@ int show_perf_probe_events(struct strfilter *filter)
2573} 2577}
2574 2578
2575static int get_new_event_name(char *buf, size_t len, const char *base, 2579static int get_new_event_name(char *buf, size_t len, const char *base,
2576 struct strlist *namelist, bool allow_suffix) 2580 struct strlist *namelist, bool ret_event,
2581 bool allow_suffix)
2577{ 2582{
2578 int i, ret; 2583 int i, ret;
2579 char *p, *nbase; 2584 char *p, *nbase;
@@ -2584,13 +2589,13 @@ static int get_new_event_name(char *buf, size_t len, const char *base,
2584 if (!nbase) 2589 if (!nbase)
2585 return -ENOMEM; 2590 return -ENOMEM;
2586 2591
2587 /* Cut off the dot suffixes (e.g. .const, .isra)*/ 2592 /* Cut off the dot suffixes (e.g. .const, .isra) and version suffixes */
2588 p = strchr(nbase, '.'); 2593 p = strpbrk(nbase, ".@");
2589 if (p && p != nbase) 2594 if (p && p != nbase)
2590 *p = '\0'; 2595 *p = '\0';
2591 2596
2592 /* Try no suffix number */ 2597 /* Try no suffix number */
2593 ret = e_snprintf(buf, len, "%s", nbase); 2598 ret = e_snprintf(buf, len, "%s%s", nbase, ret_event ? "__return" : "");
2594 if (ret < 0) { 2599 if (ret < 0) {
2595 pr_debug("snprintf() failed: %d\n", ret); 2600 pr_debug("snprintf() failed: %d\n", ret);
2596 goto out; 2601 goto out;
@@ -2625,6 +2630,14 @@ static int get_new_event_name(char *buf, size_t len, const char *base,
2625 2630
2626out: 2631out:
2627 free(nbase); 2632 free(nbase);
2633
2634 /* Final validation */
2635 if (ret >= 0 && !is_c_func_name(buf)) {
2636 pr_warning("Internal error: \"%s\" is an invalid event name.\n",
2637 buf);
2638 ret = -EINVAL;
2639 }
2640
2628 return ret; 2641 return ret;
2629} 2642}
2630 2643
@@ -2681,8 +2694,8 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
2681 group = PERFPROBE_GROUP; 2694 group = PERFPROBE_GROUP;
2682 2695
2683 /* Get an unused new event name */ 2696 /* Get an unused new event name */
2684 ret = get_new_event_name(buf, 64, event, 2697 ret = get_new_event_name(buf, 64, event, namelist,
2685 namelist, allow_suffix); 2698 tev->point.retprobe, allow_suffix);
2686 if (ret < 0) 2699 if (ret < 0)
2687 return ret; 2700 return ret;
2688 2701
@@ -2792,16 +2805,40 @@ static int find_probe_functions(struct map *map, char *name,
2792 int found = 0; 2805 int found = 0;
2793 struct symbol *sym; 2806 struct symbol *sym;
2794 struct rb_node *tmp; 2807 struct rb_node *tmp;
2808 const char *norm, *ver;
2809 char *buf = NULL;
2810 bool cut_version = true;
2795 2811
2796 if (map__load(map) < 0) 2812 if (map__load(map) < 0)
2797 return 0; 2813 return 0;
2798 2814
2815 /* If user gives a version, don't cut off the version from symbols */
2816 if (strchr(name, '@'))
2817 cut_version = false;
2818
2799 map__for_each_symbol(map, sym, tmp) { 2819 map__for_each_symbol(map, sym, tmp) {
2800 if (strglobmatch(sym->name, name)) { 2820 norm = arch__normalize_symbol_name(sym->name);
2821 if (!norm)
2822 continue;
2823
2824 if (cut_version) {
2825 /* We don't care about default symbol or not */
2826 ver = strchr(norm, '@');
2827 if (ver) {
2828 buf = strndup(norm, ver - norm);
2829 if (!buf)
2830 return -ENOMEM;
2831 norm = buf;
2832 }
2833 }
2834
2835 if (strglobmatch(norm, name)) {
2801 found++; 2836 found++;
2802 if (syms && found < probe_conf.max_probes) 2837 if (syms && found < probe_conf.max_probes)
2803 syms[found - 1] = sym; 2838 syms[found - 1] = sym;
2804 } 2839 }
2840 if (buf)
2841 zfree(&buf);
2805 } 2842 }
2806 2843
2807 return found; 2844 return found;
@@ -2847,7 +2884,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
2847 * same name but different addresses, this lists all the symbols. 2884 * same name but different addresses, this lists all the symbols.
2848 */ 2885 */
2849 num_matched_functions = find_probe_functions(map, pp->function, syms); 2886 num_matched_functions = find_probe_functions(map, pp->function, syms);
2850 if (num_matched_functions == 0) { 2887 if (num_matched_functions <= 0) {
2851 pr_err("Failed to find symbol %s in %s\n", pp->function, 2888 pr_err("Failed to find symbol %s in %s\n", pp->function,
2852 pev->target ? : "kernel"); 2889 pev->target ? : "kernel");
2853 ret = -ENOENT; 2890 ret = -ENOENT;