aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-annotate.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-annotate.c')
-rw-r--r--tools/perf/builtin-annotate.c55
1 files changed, 7 insertions, 48 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 7d39bd2b19b8..7f85c6e159a4 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -124,71 +124,30 @@ static void hist_hit(struct hist_entry *he, u64 ip)
124 h->ip[offset]); 124 h->ip[offset]);
125} 125}
126 126
127static int hist_entry__add(struct thread *thread, struct map *map, 127static int hist_entry__add(struct addr_location *al, u64 count)
128 struct symbol *sym, u64 ip, u64 count, char level)
129{ 128{
130 bool hit; 129 bool hit;
131 struct hist_entry *he = __hist_entry__add(thread, map, sym, NULL, ip, 130 struct hist_entry *he = __hist_entry__add(al, NULL, count, &hit);
132 count, level, &hit);
133 if (he == NULL) 131 if (he == NULL)
134 return -ENOMEM; 132 return -ENOMEM;
135 hist_hit(he, ip); 133 hist_hit(he, al->addr);
136 return 0; 134 return 0;
137} 135}
138 136
139static int process_sample_event(event_t *event) 137static int process_sample_event(event_t *event)
140{ 138{
141 char level; 139 struct addr_location al;
142 u64 ip = event->ip.ip;
143 struct map *map = NULL;
144 struct symbol *sym = NULL;
145 struct thread *thread = threads__findnew(event->ip.pid);
146 140
147 dump_printf("(IP, %d): %d: %p\n", event->header.misc, 141 dump_printf("(IP, %d): %d: %p\n", event->header.misc,
148 event->ip.pid, (void *)(long)ip); 142 event->ip.pid, (void *)(long)event->ip.ip);
149 143
150 if (thread == NULL) { 144 if (event__preprocess_sample(event, &al, symbol_filter) < 0) {
151 fprintf(stderr, "problem processing %d event, skipping it.\n", 145 fprintf(stderr, "problem processing %d event, skipping it.\n",
152 event->header.type); 146 event->header.type);
153 return -1; 147 return -1;
154 } 148 }
155 149
156 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); 150 if (hist_entry__add(&al, 1)) {
157
158 if (event->header.misc & PERF_RECORD_MISC_KERNEL) {
159 level = 'k';
160 sym = kernel_maps__find_function(ip, &map, symbol_filter);
161 dump_printf(" ...... dso: %s\n",
162 map ? map->dso->long_name : "<not found>");
163 } else if (event->header.misc & PERF_RECORD_MISC_USER) {
164 level = '.';
165 map = thread__find_map(thread, MAP__FUNCTION, ip);
166 if (map != NULL) {
167 ip = map->map_ip(map, ip);
168 sym = map__find_symbol(map, ip, symbol_filter);
169 } else {
170 /*
171 * If this is outside of all known maps,
172 * and is a negative address, try to look it
173 * up in the kernel dso, as it might be a
174 * vsyscall or vdso (which executes in user-mode).
175 *
176 * XXX This is nasty, we should have a symbol list in
177 * the "[vdso]" dso, but for now lets use the old
178 * trick of looking in the whole kernel symbol list.
179 */
180 if ((long long)ip < 0)
181 sym = kernel_maps__find_function(ip, &map,
182 symbol_filter);
183 }
184 dump_printf(" ...... dso: %s\n",
185 map ? map->dso->long_name : "<not found>");
186 } else {
187 level = 'H';
188 dump_printf(" ...... dso: [hypervisor]\n");
189 }
190
191 if (hist_entry__add(thread, map, sym, ip, 1, level)) {
192 fprintf(stderr, "problem incrementing symbol count, " 151 fprintf(stderr, "problem incrementing symbol count, "
193 "skipping event\n"); 152 "skipping event\n");
194 return -1; 153 return -1;