diff options
Diffstat (limited to 'tools/perf/builtin-annotate.c')
-rw-r--r-- | tools/perf/builtin-annotate.c | 55 |
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 | ||
127 | static int hist_entry__add(struct thread *thread, struct map *map, | 127 | static 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 | ||
139 | static int process_sample_event(event_t *event) | 137 | static 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; |