Blame view

tools/perf/builtin-annotate.c 13.5 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
8035e4288   Ingo Molnar   perf_counter tool...
2
3
4
5
6
7
8
9
10
11
  /*
   * builtin-annotate.c
   *
   * Builtin annotate command: Analyze the perf.data input file,
   * look up and read DSOs and symbol information and display
   * a histogram of results, along various sorting keys.
   */
  #include "builtin.h"
  
  #include "util/util.h"
8035e4288   Ingo Molnar   perf_counter tool...
12
  #include "util/color.h"
5da502585   Arnaldo Carvalho de Melo   perf_counter tool...
13
  #include <linux/list.h>
8035e4288   Ingo Molnar   perf_counter tool...
14
  #include "util/cache.h"
43cbcd8ac   Arnaldo Carvalho de Melo   perf_counter tool...
15
  #include <linux/rbtree.h>
8035e4288   Ingo Molnar   perf_counter tool...
16
  #include "util/symbol.h"
8035e4288   Ingo Molnar   perf_counter tool...
17
18
  
  #include "perf.h"
8f28827a1   Frederic Weisbecker   perf tools: Libra...
19
  #include "util/debug.h"
8035e4288   Ingo Molnar   perf_counter tool...
20

e248de331   Arnaldo Carvalho de Melo   perf tools: Impro...
21
22
  #include "util/evlist.h"
  #include "util/evsel.h"
78f7defed   Arnaldo Carvalho de Melo   perf annotate: Mo...
23
  #include "util/annotate.h"
62daacb51   Arnaldo Carvalho de Melo   perf tools: Reorg...
24
  #include "util/event.h"
4b6ab94ea   Josh Poimboeuf   perf subcmd: Crea...
25
  #include <subcmd/parse-options.h>
8035e4288   Ingo Molnar   perf_counter tool...
26
  #include "util/parse-events.h"
6baa0a5ae   Frederic Weisbecker   perf tools: Facto...
27
  #include "util/thread.h"
dd68ada2d   John Kacur   perf tools: Creat...
28
  #include "util/sort.h"
3d1d07ecd   John Kacur   perf tools: Put c...
29
  #include "util/hist.h"
94c744b6c   Arnaldo Carvalho de Melo   perf tools: Intro...
30
  #include "util/session.h"
45694aa77   Arnaldo Carvalho de Melo   perf tools: Renam...
31
  #include "util/tool.h"
f5fc14124   Jiri Olsa   perf tools: Add d...
32
  #include "util/data.h"
68e94f4eb   Irina Tirdea   perf tools: Try t...
33
  #include "arch/common.h"
70fbe0574   Peter Zijlstra   perf annotate: Ad...
34
  #include "util/block-range.h"
8035e4288   Ingo Molnar   perf_counter tool...
35

fc67297b1   Namhyung Kim   perf tools: Separ...
36
  #include <dlfcn.h>
a43783aee   Arnaldo Carvalho de Melo   perf tools: Inclu...
37
  #include <errno.h>
5d67be97f   Anton Blanchard   perf report/annot...
38
  #include <linux/bitmap.h>
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
39
  struct perf_annotate {
45694aa77   Arnaldo Carvalho de Melo   perf tools: Renam...
40
  	struct perf_tool tool;
fa10f316d   Namhyung Kim   perf annotate: Mo...
41
42
  	struct perf_session *session;
  	bool	   use_tui, use_stdio, use_gtk;
7009cc34b   Arnaldo Carvalho de Melo   perf annotate: Gr...
43
44
  	bool	   full_paths;
  	bool	   print_line;
18c9e5c56   Namhyung Kim   perf annotate: Ma...
45
  	bool	   skip_missing;
7009cc34b   Arnaldo Carvalho de Melo   perf annotate: Gr...
46
47
48
  	const char *sym_hist_filter;
  	const char *cpu_list;
  	DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
49
  };
5d67be97f   Anton Blanchard   perf report/annot...
50

70fbe0574   Peter Zijlstra   perf annotate: Ad...
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
  /*
   * Given one basic block:
   *
   *	from	to		branch_i
   *	* ----> *
   *		|
   *		| block
   *		v
   *		* ----> *
   *		from	to	branch_i+1
   *
   * where the horizontal are the branches and the vertical is the executed
   * block of instructions.
   *
   * We count, for each 'instruction', the number of blocks that covered it as
   * well as count the ratio each branch is taken.
   *
   * We can do this without knowing the actual instruction stream by keeping
   * track of the address ranges. We break down ranges such that there is no
   * overlap and iterate from the start until the end.
   *
   * @acme: once we parse the objdump output _before_ processing the samples,
   * we can easily fold the branch.cycles IPC bits in.
   */
  static void process_basic_block(struct addr_map_symbol *start,
  				struct addr_map_symbol *end,
  				struct branch_flags *flags)
  {
  	struct symbol *sym = start->sym;
  	struct annotation *notes = sym ? symbol__annotation(sym) : NULL;
  	struct block_range_iter iter;
  	struct block_range *entry;
  
  	/*
  	 * Sanity; NULL isn't executable and the CPU cannot execute backwards
  	 */
  	if (!start->addr || start->addr > end->addr)
  		return;
  
  	iter = block_range__create(start->addr, end->addr);
  	if (!block_range_iter__valid(&iter))
  		return;
  
  	/*
  	 * First block in range is a branch target.
  	 */
  	entry = block_range_iter(&iter);
  	assert(entry->is_target);
  	entry->entry++;
  
  	do {
  		entry = block_range_iter(&iter);
  
  		entry->coverage++;
  		entry->sym = sym;
  
  		if (notes)
  			notes->max_coverage = max(notes->max_coverage, entry->coverage);
  
  	} while (block_range_iter__next(&iter));
  
  	/*
  	 * Last block in rage is a branch.
  	 */
  	entry = block_range_iter(&iter);
  	assert(entry->is_branch);
  	entry->taken++;
  	if (flags->predicted)
  		entry->pred++;
  }
  
  static void process_branch_stack(struct branch_stack *bs, struct addr_location *al,
  				 struct perf_sample *sample)
  {
  	struct addr_map_symbol *prev = NULL;
  	struct branch_info *bi;
  	int i;
  
  	if (!bs || !bs->nr)
  		return;
  
  	bi = sample__resolve_bstack(sample, al);
  	if (!bi)
  		return;
  
  	for (i = bs->nr - 1; i >= 0; i--) {
  		/*
  		 * XXX filter against symbol
  		 */
  		if (prev)
  			process_basic_block(prev, &bi[i].from, &bi[i].flags);
  		prev = &bi[i].to;
  	}
  
  	free(bi);
  }
d04b35f80   Arnaldo Carvalho de Melo   perf symbols: Add...
147
  static int perf_evsel__add_sample(struct perf_evsel *evsel,
fd36f3dd7   Namhyung Kim   perf hist: Pass s...
148
  				  struct perf_sample *sample,
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
149
150
  				  struct addr_location *al,
  				  struct perf_annotate *ann)
8035e4288   Ingo Molnar   perf_counter tool...
151
  {
4ea062ed4   Arnaldo Carvalho de Melo   perf evsel: Add h...
152
  	struct hists *hists = evsel__hists(evsel);
628ada0cb   Arnaldo Carvalho de Melo   perf annotate: De...
153
  	struct hist_entry *he;
e248de331   Arnaldo Carvalho de Melo   perf tools: Impro...
154
  	int ret;
628ada0cb   Arnaldo Carvalho de Melo   perf annotate: De...
155

7009cc34b   Arnaldo Carvalho de Melo   perf annotate: Gr...
156
157
158
  	if (ann->sym_hist_filter != NULL &&
  	    (al->sym == NULL ||
  	     strcmp(ann->sym_hist_filter, al->sym->name) != 0)) {
628ada0cb   Arnaldo Carvalho de Melo   perf annotate: De...
159
  		/* We're only interested in a symbol named sym_hist_filter */
facf3f062   Arnaldo Carvalho de Melo   perf tools: Check...
160
161
162
163
  		/*
  		 * FIXME: why isn't this done in the symbol_filter when loading
  		 * the DSO?
  		 */
628ada0cb   Arnaldo Carvalho de Melo   perf annotate: De...
164
165
166
167
  		if (al->sym != NULL) {
  			rb_erase(&al->sym->rb_node,
  				 &al->map->dso->symbols[al->map->type]);
  			symbol__delete(al->sym);
c0b4dffbc   Arnaldo Carvalho de Melo   perf annotate: Re...
168
  			dso__reset_find_symbol_cache(al->map->dso);
628ada0cb   Arnaldo Carvalho de Melo   perf annotate: De...
169
170
171
  		}
  		return 0;
  	}
70fbe0574   Peter Zijlstra   perf annotate: Ad...
172
173
174
175
176
  	/*
  	 * XXX filtered samples can still have branch entires pointing into our
  	 * symbol and are missed.
  	 */
  	process_branch_stack(sample->branch_stack, al, sample);
0102ef3ec   Jiri Olsa   perf hists: Renam...
177
  	he = hists__add_entry(hists, al, NULL, NULL, NULL, sample, true);
9735abf11   Arnaldo Carvalho de Melo   perf tools: Move ...
178
  	if (he == NULL)
8035e4288   Ingo Molnar   perf_counter tool...
179
  		return -ENOMEM;
628ada0cb   Arnaldo Carvalho de Melo   perf annotate: De...
180

bab89f6ae   Taeung Song   perf hists: Pass ...
181
  	ret = hist_entry__inc_addr_samples(he, sample, evsel->idx, al->addr);
4ea062ed4   Arnaldo Carvalho de Melo   perf evsel: Add h...
182
  	hists__inc_nr_samples(hists, true);
e248de331   Arnaldo Carvalho de Melo   perf tools: Impro...
183
  	return ret;
8035e4288   Ingo Molnar   perf_counter tool...
184
  }
45694aa77   Arnaldo Carvalho de Melo   perf tools: Renam...
185
  static int process_sample_event(struct perf_tool *tool,
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
186
  				union perf_event *event,
8115d60c3   Arnaldo Carvalho de Melo   perf tools: Kill ...
187
  				struct perf_sample *sample,
9e69c2108   Arnaldo Carvalho de Melo   perf session: Pas...
188
  				struct perf_evsel *evsel,
743eb8686   Arnaldo Carvalho de Melo   perf tools: Resol...
189
  				struct machine *machine)
8035e4288   Ingo Molnar   perf_counter tool...
190
  {
45694aa77   Arnaldo Carvalho de Melo   perf tools: Renam...
191
  	struct perf_annotate *ann = container_of(tool, struct perf_annotate, tool);
1ed091c45   Arnaldo Carvalho de Melo   perf tools: Conso...
192
  	struct addr_location al;
b91fc39f4   Arnaldo Carvalho de Melo   perf machine: Pro...
193
  	int ret = 0;
6baa0a5ae   Frederic Weisbecker   perf tools: Facto...
194

bb3eb5662   Arnaldo Carvalho de Melo   perf machine: Ren...
195
  	if (machine__resolve(machine, &al, sample) < 0) {
29a9f66d7   Arnaldo Carvalho de Melo   perf tools: Adjus...
196
197
198
  		pr_warning("problem processing %d event, skipping it.
  ",
  			   event->header.type);
8035e4288   Ingo Molnar   perf_counter tool...
199
200
  		return -1;
  	}
7009cc34b   Arnaldo Carvalho de Melo   perf annotate: Gr...
201
  	if (ann->cpu_list && !test_bit(sample->cpu, ann->cpu_bitmap))
b91fc39f4   Arnaldo Carvalho de Melo   perf machine: Pro...
202
  		goto out_put;
5d67be97f   Anton Blanchard   perf report/annot...
203

d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
204
  	if (!al.filtered && perf_evsel__add_sample(evsel, sample, &al, ann)) {
29a9f66d7   Arnaldo Carvalho de Melo   perf tools: Adjus...
205
206
207
  		pr_warning("problem incrementing symbol count, "
  			   "skipping event
  ");
b91fc39f4   Arnaldo Carvalho de Melo   perf machine: Pro...
208
  		ret = -1;
8035e4288   Ingo Molnar   perf_counter tool...
209
  	}
b91fc39f4   Arnaldo Carvalho de Melo   perf machine: Pro...
210
211
212
  out_put:
  	addr_location__put(&al);
  	return ret;
8035e4288   Ingo Molnar   perf_counter tool...
213
  }
db8fd07a5   Namhyung Kim   perf annotate: Pa...
214
215
  static int hist_entry__tty_annotate(struct hist_entry *he,
  				    struct perf_evsel *evsel,
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
216
  				    struct perf_annotate *ann)
0b73da3f4   Ingo Molnar   perf_counter tool...
217
  {
db8fd07a5   Namhyung Kim   perf annotate: Pa...
218
  	return symbol__tty_annotate(he->ms.sym, he->ms.map, evsel,
7009cc34b   Arnaldo Carvalho de Melo   perf annotate: Gr...
219
  				    ann->print_line, ann->full_paths, 0, 0);
0b73da3f4   Ingo Molnar   perf_counter tool...
220
  }
c824c4338   Arnaldo Carvalho de Melo   perf tools: Stop ...
221
  static void hists__find_annotations(struct hists *hists,
db8fd07a5   Namhyung Kim   perf annotate: Pa...
222
  				    struct perf_evsel *evsel,
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
223
  				    struct perf_annotate *ann)
0b73da3f4   Ingo Molnar   perf_counter tool...
224
  {
c824c4338   Arnaldo Carvalho de Melo   perf tools: Stop ...
225
  	struct rb_node *nd = rb_first(&hists->entries), *next;
cf9580036   Arnaldo Carvalho de Melo   perf ui browser: ...
226
  	int key = K_RIGHT;
0b73da3f4   Ingo Molnar   perf_counter tool...
227

46e3e055c   Arnaldo Carvalho de Melo   perf annotate: Ad...
228
  	while (nd) {
ed52ce2e3   Arnaldo Carvalho de Melo   perf tools: Add -...
229
  		struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
78f7defed   Arnaldo Carvalho de Melo   perf annotate: Mo...
230
  		struct annotation *notes;
0b73da3f4   Ingo Molnar   perf_counter tool...
231

46e3e055c   Arnaldo Carvalho de Melo   perf annotate: Ad...
232
233
  		if (he->ms.sym == NULL || he->ms.map->dso->annotate_warned)
  			goto find_next;
0b73da3f4   Ingo Molnar   perf_counter tool...
234

78f7defed   Arnaldo Carvalho de Melo   perf annotate: Mo...
235
  		notes = symbol__annotation(he->ms.sym);
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
236
  		if (notes->src == NULL) {
46e3e055c   Arnaldo Carvalho de Melo   perf annotate: Ad...
237
  find_next:
cf9580036   Arnaldo Carvalho de Melo   perf ui browser: ...
238
  			if (key == K_LEFT)
46e3e055c   Arnaldo Carvalho de Melo   perf annotate: Ad...
239
240
241
  				nd = rb_prev(nd);
  			else
  				nd = rb_next(nd);
e42049926   Arnaldo Carvalho de Melo   perf annotate: Us...
242
  			continue;
46e3e055c   Arnaldo Carvalho de Melo   perf annotate: Ad...
243
  		}
e42049926   Arnaldo Carvalho de Melo   perf annotate: Us...
244

2b676bf06   Namhyung Kim   perf ui/gtk: Impl...
245
  		if (use_browser == 2) {
18c9e5c56   Namhyung Kim   perf annotate: Ma...
246
  			int ret;
fc67297b1   Namhyung Kim   perf tools: Separ...
247
248
249
250
251
252
253
254
255
256
257
  			int (*annotate)(struct hist_entry *he,
  					struct perf_evsel *evsel,
  					struct hist_browser_timer *hbt);
  
  			annotate = dlsym(perf_gtk_handle,
  					 "hist_entry__gtk_annotate");
  			if (annotate == NULL) {
  				ui__error("GTK browser not found!
  ");
  				return;
  			}
18c9e5c56   Namhyung Kim   perf annotate: Ma...
258

fc67297b1   Namhyung Kim   perf tools: Separ...
259
  			ret = annotate(he, evsel, NULL);
18c9e5c56   Namhyung Kim   perf annotate: Ma...
260
261
262
263
264
  			if (!ret || !ann->skip_missing)
  				return;
  
  			/* skip missing symbols */
  			nd = rb_next(nd);
2b676bf06   Namhyung Kim   perf ui/gtk: Impl...
265
  		} else if (use_browser == 1) {
db8fd07a5   Namhyung Kim   perf annotate: Pa...
266
  			key = hist_entry__tui_annotate(he, evsel, NULL);
46e3e055c   Arnaldo Carvalho de Melo   perf annotate: Ad...
267
  			switch (key) {
18c9e5c56   Namhyung Kim   perf annotate: Ma...
268
269
270
271
  			case -1:
  				if (!ann->skip_missing)
  					return;
  				/* fall through */
cf9580036   Arnaldo Carvalho de Melo   perf ui browser: ...
272
  			case K_RIGHT:
b50e003db   Arnaldo Carvalho de Melo   perf ui browser: ...
273
  				next = rb_next(nd);
46e3e055c   Arnaldo Carvalho de Melo   perf annotate: Ad...
274
  				break;
cf9580036   Arnaldo Carvalho de Melo   perf ui browser: ...
275
  			case K_LEFT:
b50e003db   Arnaldo Carvalho de Melo   perf ui browser: ...
276
  				next = rb_prev(nd);
46e3e055c   Arnaldo Carvalho de Melo   perf annotate: Ad...
277
  				break;
b50e003db   Arnaldo Carvalho de Melo   perf ui browser: ...
278
279
  			default:
  				return;
46e3e055c   Arnaldo Carvalho de Melo   perf annotate: Ad...
280
  			}
b50e003db   Arnaldo Carvalho de Melo   perf ui browser: ...
281
282
283
  
  			if (next != NULL)
  				nd = next;
46e3e055c   Arnaldo Carvalho de Melo   perf annotate: Ad...
284
  		} else {
db8fd07a5   Namhyung Kim   perf annotate: Pa...
285
  			hist_entry__tty_annotate(he, evsel, ann);
46e3e055c   Arnaldo Carvalho de Melo   perf annotate: Ad...
286
287
288
  			nd = rb_next(nd);
  			/*
  			 * Since we have a hist_entry per IP for the same
ce6f4fab4   Arnaldo Carvalho de Melo   perf annotate: Mo...
289
  			 * symbol, free he->ms.sym->src to signal we already
46e3e055c   Arnaldo Carvalho de Melo   perf annotate: Ad...
290
291
  			 * processed this symbol.
  			 */
d4957633b   Andi Kleen   perf report: Add ...
292
  			zfree(&notes->src->cycles_hist);
046625231   Arnaldo Carvalho de Melo   perf tools: Intro...
293
  			zfree(&notes->src);
46e3e055c   Arnaldo Carvalho de Melo   perf annotate: Ad...
294
  		}
0b73da3f4   Ingo Molnar   perf_counter tool...
295
  	}
0b73da3f4   Ingo Molnar   perf_counter tool...
296
  }
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
297
  static int __cmd_annotate(struct perf_annotate *ann)
8035e4288   Ingo Molnar   perf_counter tool...
298
  {
bab81b624   Li Zefan   perf annotate: Fi...
299
  	int ret;
fa10f316d   Namhyung Kim   perf annotate: Mo...
300
  	struct perf_session *session = ann->session;
e248de331   Arnaldo Carvalho de Melo   perf tools: Impro...
301
302
  	struct perf_evsel *pos;
  	u64 total_nr_samples;
94c744b6c   Arnaldo Carvalho de Melo   perf tools: Intro...
303

7009cc34b   Arnaldo Carvalho de Melo   perf annotate: Gr...
304
305
306
  	if (ann->cpu_list) {
  		ret = perf_session__cpu_bitmap(session, ann->cpu_list,
  					       ann->cpu_bitmap);
5d67be97f   Anton Blanchard   perf report/annot...
307
  		if (ret)
fa10f316d   Namhyung Kim   perf annotate: Mo...
308
  			goto out;
5d67be97f   Anton Blanchard   perf report/annot...
309
  	}
68e94f4eb   Irina Tirdea   perf tools: Try t...
310
  	if (!objdump_path) {
eebd0bfca   Arnaldo Carvalho de Melo   perf env: Rename ...
311
  		ret = perf_env__lookup_objdump(&session->header.env);
68e94f4eb   Irina Tirdea   perf tools: Try t...
312
  		if (ret)
fa10f316d   Namhyung Kim   perf annotate: Mo...
313
  			goto out;
68e94f4eb   Irina Tirdea   perf tools: Try t...
314
  	}
b7b61cbeb   Arnaldo Carvalho de Melo   perf ordered_even...
315
  	ret = perf_session__process_events(session);
bab81b624   Li Zefan   perf annotate: Fi...
316
  	if (ret)
fa10f316d   Namhyung Kim   perf annotate: Mo...
317
  		goto out;
8035e4288   Ingo Molnar   perf_counter tool...
318

62daacb51   Arnaldo Carvalho de Melo   perf tools: Reorg...
319
  	if (dump_trace) {
c8446b9bd   Arnaldo Carvalho de Melo   perf hist: Make e...
320
  		perf_session__fprintf_nr_events(session, stdout);
2a1731fb8   Arnaldo Carvalho de Melo   perf session: Rem...
321
  		perf_evlist__fprintf_nr_events(session->evlist, stdout);
fa10f316d   Namhyung Kim   perf annotate: Mo...
322
  		goto out;
62daacb51   Arnaldo Carvalho de Melo   perf tools: Reorg...
323
  	}
8035e4288   Ingo Molnar   perf_counter tool...
324

da21d1b54   Arnaldo Carvalho de Melo   perf tools: Up th...
325
  	if (verbose > 3)
b3165f414   Arnaldo Carvalho de Melo   perf session: Mov...
326
  		perf_session__fprintf(session, stdout);
8035e4288   Ingo Molnar   perf_counter tool...
327

da21d1b54   Arnaldo Carvalho de Melo   perf tools: Up th...
328
  	if (verbose > 2)
cbf696809   Arnaldo Carvalho de Melo   perf machines: Ma...
329
  		perf_session__fprintf_dsos(session, stdout);
8035e4288   Ingo Molnar   perf_counter tool...
330

e248de331   Arnaldo Carvalho de Melo   perf tools: Impro...
331
  	total_nr_samples = 0;
e5cadb93d   Arnaldo Carvalho de Melo   perf evlist: Rena...
332
  	evlist__for_each_entry(session->evlist, pos) {
4ea062ed4   Arnaldo Carvalho de Melo   perf evsel: Add h...
333
  		struct hists *hists = evsel__hists(pos);
e248de331   Arnaldo Carvalho de Melo   perf tools: Impro...
334
335
336
337
  		u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
  
  		if (nr_samples > 0) {
  			total_nr_samples += nr_samples;
c1fb5651b   Namhyung Kim   perf tools: Show ...
338
  			hists__collapse_resort(hists, NULL);
f9db0d0f1   Kan Liang   perf callchain: A...
339
340
  			/* Don't sort callchain */
  			perf_evsel__reset_sample_bit(pos, CALLCHAIN);
452ce03b1   Jiri Olsa   perf hists: Intro...
341
  			perf_evsel__output_resort(pos, NULL);
b1dd44329   Namhyung Kim   perf annotate: Ad...
342
343
344
345
  
  			if (symbol_conf.event_group &&
  			    !perf_evsel__is_group_leader(pos))
  				continue;
db8fd07a5   Namhyung Kim   perf annotate: Pa...
346
  			hists__find_annotations(hists, pos, ann);
e248de331   Arnaldo Carvalho de Melo   perf tools: Impro...
347
348
  		}
  	}
8035e4288   Ingo Molnar   perf_counter tool...
349

e248de331   Arnaldo Carvalho de Melo   perf tools: Impro...
350
  	if (total_nr_samples == 0) {
fa10f316d   Namhyung Kim   perf annotate: Mo...
351
352
353
  		ui__error("The %s file has no samples!
  ", session->file->path);
  		goto out;
e248de331   Arnaldo Carvalho de Melo   perf tools: Impro...
354
  	}
7a60ba948   Namhyung Kim   perf gtk/annotate...
355

fc67297b1   Namhyung Kim   perf tools: Separ...
356
357
358
359
360
361
362
363
  	if (use_browser == 2) {
  		void (*show_annotations)(void);
  
  		show_annotations = dlsym(perf_gtk_handle,
  					 "perf_gtk__show_annotations");
  		if (show_annotations == NULL) {
  			ui__error("GTK browser not found!
  ");
fa10f316d   Namhyung Kim   perf annotate: Mo...
364
  			goto out;
fc67297b1   Namhyung Kim   perf tools: Separ...
365
366
367
  		}
  		show_annotations();
  	}
7a60ba948   Namhyung Kim   perf gtk/annotate...
368

fa10f316d   Namhyung Kim   perf annotate: Mo...
369
  out:
bab81b624   Li Zefan   perf annotate: Fi...
370
  	return ret;
8035e4288   Ingo Molnar   perf_counter tool...
371
372
373
  }
  
  static const char * const annotate_usage[] = {
993452541   Namhyung Kim   perf annotate: Fi...
374
  	"perf annotate [<options>]",
8035e4288   Ingo Molnar   perf_counter tool...
375
376
  	NULL
  };
b0ad8ea66   Arnaldo Carvalho de Melo   perf tools: Remov...
377
  int cmd_annotate(int argc, const char **argv)
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
378
379
  {
  	struct perf_annotate annotate = {
45694aa77   Arnaldo Carvalho de Melo   perf tools: Renam...
380
  		.tool = {
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
381
382
  			.sample	= process_sample_event,
  			.mmap	= perf_event__process_mmap,
5c5e854bc   Stephane Eranian   perf tools: Add a...
383
  			.mmap2	= perf_event__process_mmap2,
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
384
  			.comm	= perf_event__process_comm,
ec4622f5f   Arnaldo Carvalho de Melo   perf annotate: Ha...
385
  			.exit	= perf_event__process_exit,
f62d3f0f4   Arnaldo Carvalho de Melo   perf event: No ne...
386
  			.fork	= perf_event__process_fork,
f3b3614a2   Hari Bathini   perf tools: Add P...
387
  			.namespaces = perf_event__process_namespaces,
6ab11f3a3   David Carrillo-Cisneros   perf annotate: Pr...
388
389
  			.attr	= perf_event__process_attr,
  			.build_id = perf_event__process_build_id,
f48495990   David Carrillo-Cisneros   perf annotate: Pr...
390
  			.tracing_data   = perf_event__process_tracing_data,
e9def1b2e   David Carrillo-Cisneros   perf tools: Add f...
391
  			.feature	= perf_event__process_feature,
0a8cb85c2   Jiri Olsa   perf tools: Renam...
392
  			.ordered_events = true,
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
393
394
  			.ordering_requires_timestamps = true,
  		},
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
395
  	};
fa10f316d   Namhyung Kim   perf annotate: Mo...
396
  	struct perf_data_file file = {
fa10f316d   Namhyung Kim   perf annotate: Mo...
397
398
  		.mode  = PERF_DATA_MODE_READ,
  	};
1ac39372e   Taeung Song   perf annotate std...
399
  	struct option options[] = {
70cb4e963   Feng Tang   perf tools: Add a...
400
  	OPT_STRING('i', "input", &input_name, "file",
8035e4288   Ingo Molnar   perf_counter tool...
401
  		    "input file name"),
ac73c5a9c   Arnaldo Carvalho de Melo   perf annotate: Al...
402
403
  	OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
  		   "only consider symbols in these dsos"),
7009cc34b   Arnaldo Carvalho de Melo   perf annotate: Gr...
404
  	OPT_STRING('s', "symbol", &annotate.sym_hist_filter, "symbol",
0b73da3f4   Ingo Molnar   perf_counter tool...
405
  		    "symbol to annotate"),
fa10f316d   Namhyung Kim   perf annotate: Mo...
406
  	OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"),
c05556421   Ian Munsie   perf: Fix endiann...
407
  	OPT_INCR('v', "verbose", &verbose,
8035e4288   Ingo Molnar   perf_counter tool...
408
  		    "be more verbose (show symbol address, etc)"),
eddaef889   Namhyung Kim   perf annotate: Ad...
409
  	OPT_BOOLEAN('q', "quiet", &quiet, "do now show any message"),
8035e4288   Ingo Molnar   perf_counter tool...
410
411
  	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
  		    "dump raw trace in ASCII"),
2b676bf06   Namhyung Kim   perf ui/gtk: Impl...
412
  	OPT_BOOLEAN(0, "gtk", &annotate.use_gtk, "Use the GTK interface"),
7009cc34b   Arnaldo Carvalho de Melo   perf annotate: Gr...
413
414
  	OPT_BOOLEAN(0, "tui", &annotate.use_tui, "Use the TUI interface"),
  	OPT_BOOLEAN(0, "stdio", &annotate.use_stdio, "Use the stdio interface"),
b32d133ae   Arnaldo Carvalho de Melo   perf symbols: Sim...
415
416
417
  	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
  		   "file", "vmlinux pathname"),
  	OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
429764873   Mike Galbraith   perf_counter tool...
418
  		    "load module symbols - WARNING: use only with -k and LIVE kernel"),
7009cc34b   Arnaldo Carvalho de Melo   perf annotate: Gr...
419
  	OPT_BOOLEAN('l', "print-line", &annotate.print_line,
301406b9c   Frederic Weisbecker   perf annotate: Pr...
420
  		    "print matching source lines (may be slow)"),
7009cc34b   Arnaldo Carvalho de Melo   perf annotate: Gr...
421
  	OPT_BOOLEAN('P', "full-paths", &annotate.full_paths,
429764873   Mike Galbraith   perf_counter tool...
422
  		    "Don't shorten the displayed pathnames"),
18c9e5c56   Namhyung Kim   perf annotate: Ma...
423
424
  	OPT_BOOLEAN(0, "skip-missing", &annotate.skip_missing,
  		    "Skip symbols that cannot be annotated"),
c8e667203   David Ahern   perf tools: make ...
425
  	OPT_STRING('C', "cpu", &annotate.cpu_list, "cpu", "list of cpus to profile"),
a70667090   He Kuang   perf tools: Set b...
426
427
428
  	OPT_CALLBACK(0, "symfs", NULL, "directory",
  		     "Look for files with symbols relative to this directory",
  		     symbol__config_symfs),
64c6f0c7f   Arnaldo Carvalho de Melo   perf tools: Make ...
429
  	OPT_BOOLEAN(0, "source", &symbol_conf.annotate_src,
3e6a2a7f3   Stephane Eranian   perf annotate: Ma...
430
  		    "Interleave source code with assembly code (default)"),
64c6f0c7f   Arnaldo Carvalho de Melo   perf tools: Make ...
431
  	OPT_BOOLEAN(0, "asm-raw", &symbol_conf.annotate_asm_raw,
3e6a2a7f3   Stephane Eranian   perf annotate: Ma...
432
  		    "Display raw encoding of assembly instructions (default)"),
f69b64f73   Andi Kleen   perf: Support set...
433
434
  	OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
  		   "Specify disassembler style (e.g. -M intel for intel syntax)"),
7a4ec9388   Maciek Borzecki   perf tools: Allow...
435
436
  	OPT_STRING(0, "objdump", &objdump_path, "path",
  		   "objdump binary to use for disassembly and annotations"),
b1dd44329   Namhyung Kim   perf annotate: Ad...
437
438
  	OPT_BOOLEAN(0, "group", &symbol_conf.event_group,
  		    "Show event group information together"),
0c4a5bcea   Martin Liška   perf annotate: Di...
439
440
  	OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
  		    "Show a column with the sum of periods"),
1ac39372e   Taeung Song   perf annotate std...
441
442
  	OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
  		    "Show a column with the number of samples"),
53fe4ba1d   Arnaldo Carvalho de Melo   perf annotate: In...
443
444
445
  	OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode",
  			     "'always' (default), 'never' or 'auto' only applicable to --stdio mode",
  			     stdio__config_color, "always"),
8035e4288   Ingo Molnar   perf_counter tool...
446
  	OPT_END()
d20deb64e   Arnaldo Carvalho de Melo   perf tools: Pass ...
447
  	};
1ac39372e   Taeung Song   perf annotate std...
448
449
450
451
  	int ret;
  
  	set_option_flag(options, 0, "show-total-period", PARSE_OPT_EXCLUSIVE);
  	set_option_flag(options, 0, "show-nr-samples", PARSE_OPT_EXCLUSIVE);
a635fc511   Arnaldo Carvalho de Melo   perf tools: Remov...
452

1ac39372e   Taeung Song   perf annotate std...
453
  	ret = hists__init();
a635fc511   Arnaldo Carvalho de Melo   perf tools: Remov...
454
455
  	if (ret < 0)
  		return ret;
8035e4288   Ingo Molnar   perf_counter tool...
456

655000e7c   Arnaldo Carvalho de Melo   perf symbols: Ado...
457
  	argc = parse_options(argc, argv, options, annotate_usage, 0);
50e19ef97   Namhyung Kim   perf annotate: Ch...
458
459
460
461
462
463
464
465
466
467
  	if (argc) {
  		/*
  		 * Special case: if there's an argument left then assume that
  		 * it's a symbol filter:
  		 */
  		if (argc > 1)
  			usage_with_options(annotate_usage, options);
  
  		annotate.sym_hist_filter = argv[0];
  	}
655000e7c   Arnaldo Carvalho de Melo   perf symbols: Ado...
468

9cef4b0b5   Taeung Song   perf annotate bro...
469
470
471
  	if (symbol_conf.show_nr_samples && annotate.use_gtk) {
  		pr_err("--show-nr-samples is not available in --gtk mode at this time
  ");
1ac39372e   Taeung Song   perf annotate std...
472
473
  		return ret;
  	}
eddaef889   Namhyung Kim   perf annotate: Ad...
474
475
  	if (quiet)
  		perf_quiet_option();
44848cdbb   Martin Liška   perf annotate: Fi...
476
  	file.path  = input_name;
fa10f316d   Namhyung Kim   perf annotate: Mo...
477
478
  	annotate.session = perf_session__new(&file, false, &annotate.tool);
  	if (annotate.session == NULL)
52e028349   Taeung Song   perf tools: Modif...
479
  		return -1;
fa10f316d   Namhyung Kim   perf annotate: Mo...
480

b01141f4f   Arnaldo Carvalho de Melo   perf annotate: In...
481
482
483
  	ret = symbol__annotation_init();
  	if (ret < 0)
  		goto out_delete;
75be6cf48   Arnaldo Carvalho de Melo   perf symbols: Mak...
484
  	symbol_conf.try_vmlinux_path = true;
0a7e6d1b6   Namhyung Kim   perf tools: Check...
485
  	ret = symbol__init(&annotate.session->header.env);
fa10f316d   Namhyung Kim   perf annotate: Mo...
486
487
  	if (ret < 0)
  		goto out_delete;
8035e4288   Ingo Molnar   perf_counter tool...
488

40184c46a   Namhyung Kim   perf tools: Pass ...
489
  	if (setup_sorting(NULL) < 0)
553099857   Namhyung Kim   perf sort: Make s...
490
  		usage_with_options(annotate_usage, options);
8035e4288   Ingo Molnar   perf_counter tool...
491

3df668e74   Namhyung Kim   perf annotate: De...
492
493
494
495
496
497
498
499
  	if (annotate.use_stdio)
  		use_browser = 0;
  	else if (annotate.use_tui)
  		use_browser = 1;
  	else if (annotate.use_gtk)
  		use_browser = 2;
  
  	setup_browser(true);
fa10f316d   Namhyung Kim   perf annotate: Mo...
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
  	ret = __cmd_annotate(&annotate);
  
  out_delete:
  	/*
  	 * Speed up the exit process, for large files this can
  	 * take quite a while.
  	 *
  	 * XXX Enable this when using valgrind or if we ever
  	 * librarize this command.
  	 *
  	 * Also experiment with obstacks to see how much speed
  	 * up we'll get here.
  	 *
  	 * perf_session__delete(session);
  	 */
  	return ret;
8035e4288   Ingo Molnar   perf_counter tool...
516
  }