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.c126
1 files changed, 89 insertions, 37 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 28733962cd80..fcfbef07b92d 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -110,13 +110,12 @@ void exit_probe_symbol_maps(void)
110static struct symbol *__find_kernel_function_by_name(const char *name, 110static struct symbol *__find_kernel_function_by_name(const char *name,
111 struct map **mapp) 111 struct map **mapp)
112{ 112{
113 return machine__find_kernel_function_by_name(host_machine, name, mapp, 113 return machine__find_kernel_function_by_name(host_machine, name, mapp);
114 NULL);
115} 114}
116 115
117static struct symbol *__find_kernel_function(u64 addr, struct map **mapp) 116static struct symbol *__find_kernel_function(u64 addr, struct map **mapp)
118{ 117{
119 return machine__find_kernel_function(host_machine, addr, mapp, NULL); 118 return machine__find_kernel_function(host_machine, addr, mapp);
120} 119}
121 120
122static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void) 121static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void)
@@ -125,7 +124,7 @@ static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void)
125 struct kmap *kmap; 124 struct kmap *kmap;
126 struct map *map = machine__kernel_map(host_machine); 125 struct map *map = machine__kernel_map(host_machine);
127 126
128 if (map__load(map, NULL) < 0) 127 if (map__load(map) < 0)
129 return NULL; 128 return NULL;
130 129
131 kmap = map__kmap(map); 130 kmap = map__kmap(map);
@@ -214,9 +213,13 @@ static int convert_exec_to_group(const char *exec, char **result)
214 goto out; 213 goto out;
215 } 214 }
216 215
217 ptr2 = strpbrk(ptr1, "-._"); 216 for (ptr2 = ptr1; ptr2 != '\0'; ptr2++) {
218 if (ptr2) 217 if (!isalnum(*ptr2) && *ptr2 != '_') {
219 *ptr2 = '\0'; 218 *ptr2 = '\0';
219 break;
220 }
221 }
222
220 ret = e_snprintf(buf, 64, "%s_%s", PERFPROBE_GROUP, ptr1); 223 ret = e_snprintf(buf, 64, "%s_%s", PERFPROBE_GROUP, ptr1);
221 if (ret < 0) 224 if (ret < 0)
222 goto out; 225 goto out;
@@ -351,9 +354,9 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso)
351 vmlinux_name = symbol_conf.vmlinux_name; 354 vmlinux_name = symbol_conf.vmlinux_name;
352 dso->load_errno = 0; 355 dso->load_errno = 0;
353 if (vmlinux_name) 356 if (vmlinux_name)
354 ret = dso__load_vmlinux(dso, map, vmlinux_name, false, NULL); 357 ret = dso__load_vmlinux(dso, map, vmlinux_name, false);
355 else 358 else
356 ret = dso__load_vmlinux_path(dso, map, NULL); 359 ret = dso__load_vmlinux_path(dso, map);
357found: 360found:
358 *pdso = dso; 361 *pdso = dso;
359 return ret; 362 return ret;
@@ -674,6 +677,10 @@ post_process_kernel_probe_trace_events(struct probe_trace_event *tevs,
674 char *tmp; 677 char *tmp;
675 int i, skipped = 0; 678 int i, skipped = 0;
676 679
680 /* Skip post process if the target is an offline kernel */
681 if (symbol_conf.ignore_vmlinux_buildid)
682 return 0;
683
677 reloc_sym = kernel_get_ref_reloc_sym(); 684 reloc_sym = kernel_get_ref_reloc_sym();
678 if (!reloc_sym) { 685 if (!reloc_sym) {
679 pr_warning("Relocated base symbol is not found!\n"); 686 pr_warning("Relocated base symbol is not found!\n");
@@ -1614,19 +1621,27 @@ out:
1614 return ret; 1621 return ret;
1615} 1622}
1616 1623
1624/* Returns true if *any* ARG is either C variable, $params or $vars. */
1625bool perf_probe_with_var(struct perf_probe_event *pev)
1626{
1627 int i = 0;
1628
1629 for (i = 0; i < pev->nargs; i++)
1630 if (is_c_varname(pev->args[i].var) ||
1631 !strcmp(pev->args[i].var, PROBE_ARG_PARAMS) ||
1632 !strcmp(pev->args[i].var, PROBE_ARG_VARS))
1633 return true;
1634 return false;
1635}
1636
1617/* Return true if this perf_probe_event requires debuginfo */ 1637/* Return true if this perf_probe_event requires debuginfo */
1618bool perf_probe_event_need_dwarf(struct perf_probe_event *pev) 1638bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
1619{ 1639{
1620 int i;
1621
1622 if (pev->point.file || pev->point.line || pev->point.lazy_line) 1640 if (pev->point.file || pev->point.line || pev->point.lazy_line)
1623 return true; 1641 return true;
1624 1642
1625 for (i = 0; i < pev->nargs; i++) 1643 if (perf_probe_with_var(pev))
1626 if (is_c_varname(pev->args[i].var) || 1644 return true;
1627 !strcmp(pev->args[i].var, "$params") ||
1628 !strcmp(pev->args[i].var, "$vars"))
1629 return true;
1630 1645
1631 return false; 1646 return false;
1632} 1647}
@@ -1987,7 +2002,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
1987 map = dso__new_map(tp->module); 2002 map = dso__new_map(tp->module);
1988 if (!map) 2003 if (!map)
1989 goto out; 2004 goto out;
1990 sym = map__find_symbol(map, addr, NULL); 2005 sym = map__find_symbol(map, addr);
1991 } else { 2006 } else {
1992 if (tp->symbol && !addr) { 2007 if (tp->symbol && !addr) {
1993 if (kernel_get_symbol_address_by_name(tp->symbol, 2008 if (kernel_get_symbol_address_by_name(tp->symbol,
@@ -2692,7 +2707,7 @@ static int find_probe_functions(struct map *map, char *name,
2692 struct symbol *sym; 2707 struct symbol *sym;
2693 struct rb_node *tmp; 2708 struct rb_node *tmp;
2694 2709
2695 if (map__load(map, NULL) < 0) 2710 if (map__load(map) < 0)
2696 return 0; 2711 return 0;
2697 2712
2698 map__for_each_symbol(map, sym, tmp) { 2713 map__for_each_symbol(map, sym, tmp) {
@@ -3207,6 +3222,52 @@ int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs)
3207 return 0; 3222 return 0;
3208} 3223}
3209 3224
3225static int show_probe_trace_event(struct probe_trace_event *tev)
3226{
3227 char *buf = synthesize_probe_trace_command(tev);
3228
3229 if (!buf) {
3230 pr_debug("Failed to synthesize probe trace event.\n");
3231 return -EINVAL;
3232 }
3233
3234 /* Showing definition always go stdout */
3235 printf("%s\n", buf);
3236 free(buf);
3237
3238 return 0;
3239}
3240
3241int show_probe_trace_events(struct perf_probe_event *pevs, int npevs)
3242{
3243 struct strlist *namelist = strlist__new(NULL, NULL);
3244 struct probe_trace_event *tev;
3245 struct perf_probe_event *pev;
3246 int i, j, ret = 0;
3247
3248 if (!namelist)
3249 return -ENOMEM;
3250
3251 for (j = 0; j < npevs && !ret; j++) {
3252 pev = &pevs[j];
3253 for (i = 0; i < pev->ntevs && !ret; i++) {
3254 tev = &pev->tevs[i];
3255 /* Skip if the symbol is out of .text or blacklisted */
3256 if (!tev->point.symbol && !pev->uprobes)
3257 continue;
3258
3259 /* Set new name for tev (and update namelist) */
3260 ret = probe_trace_event__set_name(tev, pev,
3261 namelist, true);
3262 if (!ret)
3263 ret = show_probe_trace_event(tev);
3264 }
3265 }
3266 strlist__delete(namelist);
3267
3268 return ret;
3269}
3270
3210int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs) 3271int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs)
3211{ 3272{
3212 int i, ret = 0; 3273 int i, ret = 0;
@@ -3289,24 +3350,10 @@ out:
3289 return ret; 3350 return ret;
3290} 3351}
3291 3352
3292/* TODO: don't use a global variable for filter ... */
3293static struct strfilter *available_func_filter;
3294
3295/*
3296 * If a symbol corresponds to a function with global binding and
3297 * matches filter return 0. For all others return 1.
3298 */
3299static int filter_available_functions(struct map *map __maybe_unused,
3300 struct symbol *sym)
3301{
3302 if (strfilter__compare(available_func_filter, sym->name))
3303 return 0;
3304 return 1;
3305}
3306
3307int show_available_funcs(const char *target, struct strfilter *_filter, 3353int show_available_funcs(const char *target, struct strfilter *_filter,
3308 bool user) 3354 bool user)
3309{ 3355{
3356 struct rb_node *nd;
3310 struct map *map; 3357 struct map *map;
3311 int ret; 3358 int ret;
3312 3359
@@ -3324,9 +3371,7 @@ int show_available_funcs(const char *target, struct strfilter *_filter,
3324 return -EINVAL; 3371 return -EINVAL;
3325 } 3372 }
3326 3373
3327 /* Load symbols with given filter */ 3374 ret = map__load(map);
3328 available_func_filter = _filter;
3329 ret = map__load(map, filter_available_functions);
3330 if (ret) { 3375 if (ret) {
3331 if (ret == -2) { 3376 if (ret == -2) {
3332 char *str = strfilter__string(_filter); 3377 char *str = strfilter__string(_filter);
@@ -3343,7 +3388,14 @@ int show_available_funcs(const char *target, struct strfilter *_filter,
3343 3388
3344 /* Show all (filtered) symbols */ 3389 /* Show all (filtered) symbols */
3345 setup_pager(); 3390 setup_pager();
3346 dso__fprintf_symbols_by_name(map->dso, map->type, stdout); 3391
3392 for (nd = rb_first(&map->dso->symbol_names[map->type]); nd; nd = rb_next(nd)) {
3393 struct symbol_name_rb_node *pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
3394
3395 if (strfilter__compare(_filter, pos->sym.name))
3396 printf("%s\n", pos->sym.name);
3397 }
3398
3347end: 3399end:
3348 if (user) { 3400 if (user) {
3349 map__put(map); 3401 map__put(map);