xref: /openbmc/linux/tools/perf/util/evsel_fprintf.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2fd20e811SArnaldo Carvalho de Melo #include <inttypes.h>
325da4fabSArnaldo Carvalho de Melo #include <stdio.h>
425da4fabSArnaldo Carvalho de Melo #include <stdbool.h>
525da4fabSArnaldo Carvalho de Melo #include "util/evlist.h"
6ca125277SArnaldo Carvalho de Melo #include "evsel.h"
79c9e754fSArnaldo Carvalho de Melo #include "util/evsel_fprintf.h"
825da4fabSArnaldo Carvalho de Melo #include "util/event.h"
925da4fabSArnaldo Carvalho de Melo #include "callchain.h"
108ec20b17SArnaldo Carvalho de Melo #include "map.h"
1125da4fabSArnaldo Carvalho de Melo #include "strlist.h"
12325fbff5SNamhyung Kim #include "symbol.h"
1357d7ecfdSLexi Shao #include "srcline.h"
1425da4fabSArnaldo Carvalho de Melo #include "dso.h"
15378ef0f5SIan Rogers 
16378ef0f5SIan Rogers #ifdef HAVE_LIBTRACEEVENT
17378ef0f5SIan Rogers #include <traceevent/event-parse.h>
18378ef0f5SIan Rogers #endif
1925da4fabSArnaldo Carvalho de Melo 
comma_fprintf(FILE * fp,bool * first,const char * fmt,...)2025da4fabSArnaldo Carvalho de Melo static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...)
2125da4fabSArnaldo Carvalho de Melo {
2225da4fabSArnaldo Carvalho de Melo 	va_list args;
2325da4fabSArnaldo Carvalho de Melo 	int ret = 0;
2425da4fabSArnaldo Carvalho de Melo 
2525da4fabSArnaldo Carvalho de Melo 	if (!*first) {
2625da4fabSArnaldo Carvalho de Melo 		ret += fprintf(fp, ",");
2725da4fabSArnaldo Carvalho de Melo 	} else {
2825da4fabSArnaldo Carvalho de Melo 		ret += fprintf(fp, ":");
2925da4fabSArnaldo Carvalho de Melo 		*first = false;
3025da4fabSArnaldo Carvalho de Melo 	}
3125da4fabSArnaldo Carvalho de Melo 
3225da4fabSArnaldo Carvalho de Melo 	va_start(args, fmt);
3325da4fabSArnaldo Carvalho de Melo 	ret += vfprintf(fp, fmt, args);
3425da4fabSArnaldo Carvalho de Melo 	va_end(args);
3525da4fabSArnaldo Carvalho de Melo 	return ret;
3625da4fabSArnaldo Carvalho de Melo }
3725da4fabSArnaldo Carvalho de Melo 
__print_attr__fprintf(FILE * fp,const char * name,const char * val,void * priv)3825da4fabSArnaldo Carvalho de Melo static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv)
3925da4fabSArnaldo Carvalho de Melo {
4025da4fabSArnaldo Carvalho de Melo 	return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val);
4125da4fabSArnaldo Carvalho de Melo }
422dbfc945SArnaldo Carvalho de Melo 
evsel__fprintf(struct evsel * evsel,struct perf_attr_details * details,FILE * fp)4325da4fabSArnaldo Carvalho de Melo int evsel__fprintf(struct evsel *evsel, struct perf_attr_details *details, FILE *fp)
4425da4fabSArnaldo Carvalho de Melo {
4525da4fabSArnaldo Carvalho de Melo 	bool first = true;
4625da4fabSArnaldo Carvalho de Melo 	int printed = 0;
4725da4fabSArnaldo Carvalho de Melo 
4832dcd021SJiri Olsa 	if (details->event_group) {
4925da4fabSArnaldo Carvalho de Melo 		struct evsel *pos;
50c754c382SArnaldo Carvalho de Melo 
5125da4fabSArnaldo Carvalho de Melo 		if (!evsel__is_group_leader(evsel))
5225da4fabSArnaldo Carvalho de Melo 			return 0;
535643b1a5SJiri Olsa 
5425da4fabSArnaldo Carvalho de Melo 		if (evsel->core.nr_members > 1)
5525da4fabSArnaldo Carvalho de Melo 			printed += fprintf(fp, "%s{", evsel->group_name ?: "");
568ab2e96dSArnaldo Carvalho de Melo 
5725da4fabSArnaldo Carvalho de Melo 		printed += fprintf(fp, "%s", evsel__name(evsel));
588ab2e96dSArnaldo Carvalho de Melo 		for_each_group_member(pos, evsel)
5925da4fabSArnaldo Carvalho de Melo 			printed += fprintf(fp, ",%s", evsel__name(pos));
605643b1a5SJiri Olsa 
6125da4fabSArnaldo Carvalho de Melo 		if (evsel->core.nr_members > 1)
6225da4fabSArnaldo Carvalho de Melo 			printed += fprintf(fp, "}");
6325da4fabSArnaldo Carvalho de Melo 		goto out;
6425da4fabSArnaldo Carvalho de Melo 	}
658ab2e96dSArnaldo Carvalho de Melo 
6625da4fabSArnaldo Carvalho de Melo 	printed += fprintf(fp, "%s", evsel__name(evsel));
6725da4fabSArnaldo Carvalho de Melo 
681fc632ceSJiri Olsa 	if (details->verbose) {
6925da4fabSArnaldo Carvalho de Melo 		printed += perf_event_attr__fprintf(fp, &evsel->core.attr,
7025da4fabSArnaldo Carvalho de Melo 						    __print_attr__fprintf, &first);
7125da4fabSArnaldo Carvalho de Melo 	} else if (details->freq) {
7225da4fabSArnaldo Carvalho de Melo 		const char *term = "sample_freq";
731fc632ceSJiri Olsa 
7425da4fabSArnaldo Carvalho de Melo 		if (!evsel->core.attr.freq)
7525da4fabSArnaldo Carvalho de Melo 			term = "sample_period";
7625da4fabSArnaldo Carvalho de Melo 
771fc632ceSJiri Olsa 		printed += comma_fprintf(fp, &first, " %s=%" PRIu64,
7825da4fabSArnaldo Carvalho de Melo 					 term, (u64)evsel->core.attr.sample_freq);
7925da4fabSArnaldo Carvalho de Melo 	}
80378ef0f5SIan Rogers 
8125da4fabSArnaldo Carvalho de Melo #ifdef HAVE_LIBTRACEEVENT
822c92f982STzvetomir Stoyanov (VMware) 	if (details->trace_fields) {
8325da4fabSArnaldo Carvalho de Melo 		struct tep_format_field *field;
841fc632ceSJiri Olsa 
8525da4fabSArnaldo Carvalho de Melo 		if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) {
8625da4fabSArnaldo Carvalho de Melo 			printed += comma_fprintf(fp, &first, " (not a tracepoint)");
8725da4fabSArnaldo Carvalho de Melo 			goto out;
8825da4fabSArnaldo Carvalho de Melo 		}
8925da4fabSArnaldo Carvalho de Melo 
9025da4fabSArnaldo Carvalho de Melo 		field = evsel->tp_format->format.fields;
9125da4fabSArnaldo Carvalho de Melo 		if (field == NULL) {
9225da4fabSArnaldo Carvalho de Melo 			printed += comma_fprintf(fp, &first, " (no trace field)");
9325da4fabSArnaldo Carvalho de Melo 			goto out;
9425da4fabSArnaldo Carvalho de Melo 		}
9525da4fabSArnaldo Carvalho de Melo 
9625da4fabSArnaldo Carvalho de Melo 		printed += comma_fprintf(fp, &first, " trace_fields: %s", field->name);
9725da4fabSArnaldo Carvalho de Melo 
9825da4fabSArnaldo Carvalho de Melo 		field = field->next;
9925da4fabSArnaldo Carvalho de Melo 		while (field) {
10025da4fabSArnaldo Carvalho de Melo 			printed += comma_fprintf(fp, &first, "%s", field->name);
10125da4fabSArnaldo Carvalho de Melo 			field = field->next;
10225da4fabSArnaldo Carvalho de Melo 		}
103378ef0f5SIan Rogers 	}
10425da4fabSArnaldo Carvalho de Melo #endif
10525da4fabSArnaldo Carvalho de Melo out:
10625da4fabSArnaldo Carvalho de Melo 	fputc('\n', fp);
10725da4fabSArnaldo Carvalho de Melo 	return ++printed;
10825da4fabSArnaldo Carvalho de Melo }
109142544a9SJiri Olsa 
11025da4fabSArnaldo Carvalho de Melo #ifndef PYTHON_PERF
sample__fprintf_callchain(struct perf_sample * sample,int left_alignment,unsigned int print_opts,struct callchain_cursor * cursor,struct strlist * bt_stop_list,FILE * fp)11125da4fabSArnaldo Carvalho de Melo int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
1129620bc36SArnaldo Carvalho de Melo 			      unsigned int print_opts, struct callchain_cursor *cursor,
11325da4fabSArnaldo Carvalho de Melo 			      struct strlist *bt_stop_list, FILE *fp)
11425da4fabSArnaldo Carvalho de Melo {
11525da4fabSArnaldo Carvalho de Melo 	int printed = 0;
11625da4fabSArnaldo Carvalho de Melo 	struct callchain_cursor_node *node;
11725da4fabSArnaldo Carvalho de Melo 	int print_ip = print_opts & EVSEL__PRINT_IP;
11825da4fabSArnaldo Carvalho de Melo 	int print_sym = print_opts & EVSEL__PRINT_SYM;
11925da4fabSArnaldo Carvalho de Melo 	int print_dso = print_opts & EVSEL__PRINT_DSO;
12025da4fabSArnaldo Carvalho de Melo 	int print_dsoff = print_opts & EVSEL__PRINT_DSOFF;
12125da4fabSArnaldo Carvalho de Melo 	int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
12225da4fabSArnaldo Carvalho de Melo 	int print_oneline = print_opts & EVSEL__PRINT_ONELINE;
12369b7e480SNamhyung Kim 	int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
1242d9bbf6eSNamhyung Kim 	int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
12525da4fabSArnaldo Carvalho de Melo 	int print_arrow = print_opts & EVSEL__PRINT_CALLCHAIN_ARROW;
12669b7e480SNamhyung Kim 	int print_skip_ignored = print_opts & EVSEL__PRINT_SKIP_IGNORED;
12725da4fabSArnaldo Carvalho de Melo 	char s = print_oneline ? ' ' : '\t';
12825da4fabSArnaldo Carvalho de Melo 	bool first = true;
12925da4fabSArnaldo Carvalho de Melo 
13025da4fabSArnaldo Carvalho de Melo 	if (cursor == NULL)
13125da4fabSArnaldo Carvalho de Melo 		return fprintf(fp, "<not enough memory for the callchain cursor>%s", print_oneline ? "" : "\n");
13225da4fabSArnaldo Carvalho de Melo 
13325da4fabSArnaldo Carvalho de Melo 	if (sample->callchain) {
1345f0fef8aSArnaldo Carvalho de Melo 		callchain_cursor_commit(cursor);
1355f0fef8aSArnaldo Carvalho de Melo 
13625da4fabSArnaldo Carvalho de Melo 		while (1) {
13725da4fabSArnaldo Carvalho de Melo 			struct symbol *sym;
13825da4fabSArnaldo Carvalho de Melo 			struct map *map;
13925da4fabSArnaldo Carvalho de Melo 			u64 addr = 0;
14025da4fabSArnaldo Carvalho de Melo 
14125da4fabSArnaldo Carvalho de Melo 			node = callchain_cursor_current(cursor);
1425f0fef8aSArnaldo Carvalho de Melo 			if (!node)
1435f0fef8aSArnaldo Carvalho de Melo 				break;
1445f0fef8aSArnaldo Carvalho de Melo 
1455f0fef8aSArnaldo Carvalho de Melo 			sym = node->ms.sym;
1462d9bbf6eSNamhyung Kim 			map = node->ms.map;
1472d9bbf6eSNamhyung Kim 
14825da4fabSArnaldo Carvalho de Melo 			if (sym && sym->ignore && print_skip_ignored)
14925da4fabSArnaldo Carvalho de Melo 				goto next;
15069b7e480SNamhyung Kim 
15169b7e480SNamhyung Kim 			printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
15269b7e480SNamhyung Kim 
1535f0fef8aSArnaldo Carvalho de Melo 			if (print_arrow && !first)
15478a1f7cdSIan Rogers 				printed += fprintf(fp, " <-");
15525da4fabSArnaldo Carvalho de Melo 
156*0e20f431SChangbin Du 			if (map)
15757d7ecfdSLexi Shao 				addr = map__map_ip(map, node->ip);
15857d7ecfdSLexi Shao 
15925da4fabSArnaldo Carvalho de Melo 			if (print_ip)
16025da4fabSArnaldo Carvalho de Melo 				printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);
16125da4fabSArnaldo Carvalho de Melo 
1625f0fef8aSArnaldo Carvalho de Melo 			if (print_sym) {
16325da4fabSArnaldo Carvalho de Melo 				struct addr_location node_al;
16425da4fabSArnaldo Carvalho de Melo 
1655f0fef8aSArnaldo Carvalho de Melo 				addr_location__init(&node_al);
166a8763445SNamhyung Kim 				printed += fprintf(fp, " ");
167a8763445SNamhyung Kim 				node_al.addr = addr;
16825da4fabSArnaldo Carvalho de Melo 				node_al.map  = map__get(map);
1695f0fef8aSArnaldo Carvalho de Melo 
17025da4fabSArnaldo Carvalho de Melo 				if (print_symoffset) {
17125da4fabSArnaldo Carvalho de Melo 					printed += __symbol__fprintf_symname_offs(sym, &node_al,
17225da4fabSArnaldo Carvalho de Melo 										  print_unknown_as_addr,
17325da4fabSArnaldo Carvalho de Melo 										  true, fp);
1745f0fef8aSArnaldo Carvalho de Melo 				} else {
17525da4fabSArnaldo Carvalho de Melo 					printed += __symbol__fprintf_symname(sym, &node_al,
1765f0fef8aSArnaldo Carvalho de Melo 									     print_unknown_as_addr, fp);
17725da4fabSArnaldo Carvalho de Melo 				}
17825da4fabSArnaldo Carvalho de Melo 				addr_location__exit(&node_al);
17925da4fabSArnaldo Carvalho de Melo 			}
18025da4fabSArnaldo Carvalho de Melo 
1815f0fef8aSArnaldo Carvalho de Melo 			if (print_dso && (!sym || !sym->inlined))
18225da4fabSArnaldo Carvalho de Melo 				printed += map__fprintf_dsoname_dsoff(map, print_dsoff, addr, fp);
1835f0fef8aSArnaldo Carvalho de Melo 
1849628b56dSMilian Wolff 			if (print_srcline)
1859628b56dSMilian Wolff 				printed += map__fprintf_srcline(map, addr, "\n  ", fp);
18625da4fabSArnaldo Carvalho de Melo 
18725da4fabSArnaldo Carvalho de Melo 			if (sym && sym->inlined)
188e7a06a53SAdrian Hunter 				printed += fprintf(fp, " (inlined)");
189dd2e18e9SAndi Kleen 
1905f0fef8aSArnaldo Carvalho de Melo 			if (!print_oneline)
1915f0fef8aSArnaldo Carvalho de Melo 				printed += fprintf(fp, "\n");
19264eff7d9SDavid Ahern 
19364eff7d9SDavid Ahern 			/* Add srccode here too? */
19464eff7d9SDavid Ahern 			if (bt_stop_list && sym &&
19569b7e480SNamhyung Kim 			    strlist__has_entry(bt_stop_list, sym->name)) {
1962d9bbf6eSNamhyung Kim 				break;
1972d9bbf6eSNamhyung Kim 			}
19825da4fabSArnaldo Carvalho de Melo 
19925da4fabSArnaldo Carvalho de Melo 			first = false;
20025da4fabSArnaldo Carvalho de Melo next:
20125da4fabSArnaldo Carvalho de Melo 			callchain_cursor_advance(cursor);
20225da4fabSArnaldo Carvalho de Melo 		}
20325da4fabSArnaldo Carvalho de Melo 	}
20425da4fabSArnaldo Carvalho de Melo 
20525da4fabSArnaldo Carvalho de Melo 	return printed;
2069620bc36SArnaldo Carvalho de Melo }
20725da4fabSArnaldo Carvalho de Melo 
sample__fprintf_sym(struct perf_sample * sample,struct addr_location * al,int left_alignment,unsigned int print_opts,struct callchain_cursor * cursor,struct strlist * bt_stop_list,FILE * fp)20825da4fabSArnaldo Carvalho de Melo int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
20925da4fabSArnaldo Carvalho de Melo 			int left_alignment, unsigned int print_opts,
21025da4fabSArnaldo Carvalho de Melo 			struct callchain_cursor *cursor, struct strlist *bt_stop_list, FILE *fp)
21125da4fabSArnaldo Carvalho de Melo {
21225da4fabSArnaldo Carvalho de Melo 	int printed = 0;
21325da4fabSArnaldo Carvalho de Melo 	int print_ip = print_opts & EVSEL__PRINT_IP;
21425da4fabSArnaldo Carvalho de Melo 	int print_sym = print_opts & EVSEL__PRINT_SYM;
21525da4fabSArnaldo Carvalho de Melo 	int print_dso = print_opts & EVSEL__PRINT_DSO;
21625da4fabSArnaldo Carvalho de Melo 	int print_dsoff = print_opts & EVSEL__PRINT_DSOFF;
2179620bc36SArnaldo Carvalho de Melo 	int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
2189620bc36SArnaldo Carvalho de Melo 	int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
219e7a06a53SAdrian Hunter 	int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
22025da4fabSArnaldo Carvalho de Melo 
22125da4fabSArnaldo Carvalho de Melo 	if (cursor != NULL) {
22225da4fabSArnaldo Carvalho de Melo 		printed += sample__fprintf_callchain(sample, left_alignment, print_opts,
22325da4fabSArnaldo Carvalho de Melo 						     cursor, bt_stop_list, fp);
22425da4fabSArnaldo Carvalho de Melo 	} else {
22525da4fabSArnaldo Carvalho de Melo 		printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
22625da4fabSArnaldo Carvalho de Melo 
22725da4fabSArnaldo Carvalho de Melo 		if (print_ip)
22825da4fabSArnaldo Carvalho de Melo 			printed += fprintf(fp, "%16" PRIx64, sample->ip);
229a8763445SNamhyung Kim 
230a8763445SNamhyung Kim 		if (print_sym) {
23125da4fabSArnaldo Carvalho de Melo 			printed += fprintf(fp, " ");
23225da4fabSArnaldo Carvalho de Melo 			if (print_symoffset) {
23325da4fabSArnaldo Carvalho de Melo 				printed += __symbol__fprintf_symname_offs(al->sym, al,
23425da4fabSArnaldo Carvalho de Melo 									  print_unknown_as_addr,
23525da4fabSArnaldo Carvalho de Melo 									  true, fp);
23625da4fabSArnaldo Carvalho de Melo 			} else {
23725da4fabSArnaldo Carvalho de Melo 				printed += __symbol__fprintf_symname(al->sym, al,
23825da4fabSArnaldo Carvalho de Melo 								     print_unknown_as_addr, fp);
23925da4fabSArnaldo Carvalho de Melo 			}
24025da4fabSArnaldo Carvalho de Melo 		}
24125da4fabSArnaldo Carvalho de Melo 
24225da4fabSArnaldo Carvalho de Melo 		if (print_dso)
24325da4fabSArnaldo Carvalho de Melo 			printed += map__fprintf_dsoname_dsoff(al->map, print_dsoff, al->addr, fp);
24425da4fabSArnaldo Carvalho de Melo 
24525da4fabSArnaldo Carvalho de Melo 		if (print_srcline)
24625da4fabSArnaldo Carvalho de Melo 			printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
24725da4fabSArnaldo Carvalho de Melo 	}
24825da4fabSArnaldo Carvalho de Melo 
249142544a9SJiri Olsa 	return printed;
250 }
251 #endif /* PYTHON_PERF */
252