diff options
Diffstat (limited to 'tools/perf/util/probe-event.c')
| -rw-r--r-- | tools/perf/util/probe-event.c | 126 | 
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..d281ae2b54e8 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)  static struct symbol *__find_kernel_function_by_name(const char *name,  						     struct map **mapp)  { -	return machine__find_kernel_function_by_name(host_machine, name, mapp, -						     NULL); +	return machine__find_kernel_function_by_name(host_machine, name, mapp);  }  static struct symbol *__find_kernel_function(u64 addr, struct map **mapp)  { -	return machine__find_kernel_function(host_machine, addr, mapp, NULL); +	return machine__find_kernel_function(host_machine, addr, mapp);  }  static 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)  	struct kmap *kmap;  	struct map *map = machine__kernel_map(host_machine); -	if (map__load(map, NULL) < 0) +	if (map__load(map) < 0)  		return NULL;  	kmap = map__kmap(map); @@ -214,9 +213,13 @@ static int convert_exec_to_group(const char *exec, char **result)  		goto out;  	} -	ptr2 = strpbrk(ptr1, "-._"); -	if (ptr2) -		*ptr2 = '\0'; +	for (ptr2 = ptr1; *ptr2 != '\0'; ptr2++) { +		if (!isalnum(*ptr2) && *ptr2 != '_') { +			*ptr2 = '\0'; +			break; +		} +	} +  	ret = e_snprintf(buf, 64, "%s_%s", PERFPROBE_GROUP, ptr1);  	if (ret < 0)  		goto out; @@ -351,9 +354,9 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso)  	vmlinux_name = symbol_conf.vmlinux_name;  	dso->load_errno = 0;  	if (vmlinux_name) -		ret = dso__load_vmlinux(dso, map, vmlinux_name, false, NULL); +		ret = dso__load_vmlinux(dso, map, vmlinux_name, false);  	else -		ret = dso__load_vmlinux_path(dso, map, NULL); +		ret = dso__load_vmlinux_path(dso, map);  found:  	*pdso = dso;  	return ret; @@ -674,6 +677,10 @@ post_process_kernel_probe_trace_events(struct probe_trace_event *tevs,  	char *tmp;  	int i, skipped = 0; +	/* Skip post process if the target is an offline kernel */ +	if (symbol_conf.ignore_vmlinux_buildid) +		return 0; +  	reloc_sym = kernel_get_ref_reloc_sym();  	if (!reloc_sym) {  		pr_warning("Relocated base symbol is not found!\n"); @@ -1614,19 +1621,27 @@ out:  	return ret;  } +/* Returns true if *any* ARG is either C variable, $params or $vars. */ +bool perf_probe_with_var(struct perf_probe_event *pev) +{ +	int i = 0; + +	for (i = 0; i < pev->nargs; i++) +		if (is_c_varname(pev->args[i].var)              || +		    !strcmp(pev->args[i].var, PROBE_ARG_PARAMS) || +		    !strcmp(pev->args[i].var, PROBE_ARG_VARS)) +			return true; +	return false; +} +  /* Return true if this perf_probe_event requires debuginfo */  bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)  { -	int i; -  	if (pev->point.file || pev->point.line || pev->point.lazy_line)  		return true; -	for (i = 0; i < pev->nargs; i++) -		if (is_c_varname(pev->args[i].var) || -		    !strcmp(pev->args[i].var, "$params") || -		    !strcmp(pev->args[i].var, "$vars")) -			return true; +	if (perf_probe_with_var(pev)) +		return true;  	return false;  } @@ -1987,7 +2002,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,  		map = dso__new_map(tp->module);  		if (!map)  			goto out; -		sym = map__find_symbol(map, addr, NULL); +		sym = map__find_symbol(map, addr);  	} else {  		if (tp->symbol && !addr) {  			if (kernel_get_symbol_address_by_name(tp->symbol, @@ -2692,7 +2707,7 @@ static int find_probe_functions(struct map *map, char *name,  	struct symbol *sym;  	struct rb_node *tmp; -	if (map__load(map, NULL) < 0) +	if (map__load(map) < 0)  		return 0;  	map__for_each_symbol(map, sym, tmp) { @@ -3207,6 +3222,52 @@ int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs)  	return 0;  } +static int show_probe_trace_event(struct probe_trace_event *tev) +{ +	char *buf = synthesize_probe_trace_command(tev); + +	if (!buf) { +		pr_debug("Failed to synthesize probe trace event.\n"); +		return -EINVAL; +	} + +	/* Showing definition always go stdout */ +	printf("%s\n", buf); +	free(buf); + +	return 0; +} + +int show_probe_trace_events(struct perf_probe_event *pevs, int npevs) +{ +	struct strlist *namelist = strlist__new(NULL, NULL); +	struct probe_trace_event *tev; +	struct perf_probe_event *pev; +	int i, j, ret = 0; + +	if (!namelist) +		return -ENOMEM; + +	for (j = 0; j < npevs && !ret; j++) { +		pev = &pevs[j]; +		for (i = 0; i < pev->ntevs && !ret; i++) { +			tev = &pev->tevs[i]; +			/* Skip if the symbol is out of .text or blacklisted */ +			if (!tev->point.symbol && !pev->uprobes) +				continue; + +			/* Set new name for tev (and update namelist) */ +			ret = probe_trace_event__set_name(tev, pev, +							  namelist, true); +			if (!ret) +				ret = show_probe_trace_event(tev); +		} +	} +	strlist__delete(namelist); + +	return ret; +} +  int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs)  {  	int i, ret = 0; @@ -3289,24 +3350,10 @@ out:  	return ret;  } -/* TODO: don't use a global variable for filter ... */ -static struct strfilter *available_func_filter; - -/* - * If a symbol corresponds to a function with global binding and - * matches filter return 0. For all others return 1. - */ -static int filter_available_functions(struct map *map __maybe_unused, -				      struct symbol *sym) -{ -	if (strfilter__compare(available_func_filter, sym->name)) -		return 0; -	return 1; -} -  int show_available_funcs(const char *target, struct strfilter *_filter,  					bool user)  { +        struct rb_node *nd;  	struct map *map;  	int ret; @@ -3324,9 +3371,7 @@ int show_available_funcs(const char *target, struct strfilter *_filter,  		return -EINVAL;  	} -	/* Load symbols with given filter */ -	available_func_filter = _filter; -	ret = map__load(map, filter_available_functions); +	ret = map__load(map);  	if (ret) {  		if (ret == -2) {  			char *str = strfilter__string(_filter); @@ -3343,7 +3388,14 @@ int show_available_funcs(const char *target, struct strfilter *_filter,  	/* Show all (filtered) symbols */  	setup_pager(); -	dso__fprintf_symbols_by_name(map->dso, map->type, stdout); + +        for (nd = rb_first(&map->dso->symbol_names[map->type]); nd; nd = rb_next(nd)) { +		struct symbol_name_rb_node *pos = rb_entry(nd, struct symbol_name_rb_node, rb_node); + +		if (strfilter__compare(_filter, pos->sym.name)) +			printf("%s\n", pos->sym.name); +        } +  end:  	if (user) {  		map__put(map);  | 
