diff options
| -rw-r--r-- | tools/perf/util/ui/browsers/annotate.c | 94 |
1 files changed, 48 insertions, 46 deletions
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 5cf9b78682aa..dbf8d3f6b567 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c | |||
| @@ -245,6 +245,50 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser) | |||
| 245 | return true; | 245 | return true; |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | static bool annotate_browser__callq(struct annotate_browser *browser, | ||
| 249 | int evidx, void (*timer)(void *arg), | ||
| 250 | void *arg, int delay_secs) | ||
| 251 | { | ||
| 252 | struct map_symbol *ms = browser->b.priv; | ||
| 253 | struct symbol *sym = ms->sym; | ||
| 254 | struct annotation *notes; | ||
| 255 | struct symbol *target; | ||
| 256 | char *s = strstr(browser->selection->line, "callq "); | ||
| 257 | u64 ip; | ||
| 258 | |||
| 259 | if (s == NULL) | ||
| 260 | return false; | ||
| 261 | |||
| 262 | s = strchr(s, ' '); | ||
| 263 | if (s++ == NULL) { | ||
| 264 | ui_helpline__puts("Invallid callq instruction."); | ||
| 265 | return true; | ||
| 266 | } | ||
| 267 | |||
| 268 | ip = strtoull(s, NULL, 16); | ||
| 269 | ip = ms->map->map_ip(ms->map, ip); | ||
| 270 | target = map__find_symbol(ms->map, ip, NULL); | ||
| 271 | if (target == NULL) { | ||
| 272 | ui_helpline__puts("The called function was not found."); | ||
| 273 | return true; | ||
| 274 | } | ||
| 275 | |||
| 276 | notes = symbol__annotation(target); | ||
| 277 | pthread_mutex_lock(¬es->lock); | ||
| 278 | |||
| 279 | if (notes->src == NULL && symbol__alloc_hist(target) < 0) { | ||
| 280 | pthread_mutex_unlock(¬es->lock); | ||
| 281 | ui__warning("Not enough memory for annotating '%s' symbol!\n", | ||
| 282 | target->name); | ||
| 283 | return true; | ||
| 284 | } | ||
| 285 | |||
| 286 | pthread_mutex_unlock(¬es->lock); | ||
| 287 | symbol__tui_annotate(target, ms->map, evidx, timer, arg, delay_secs); | ||
| 288 | ui_browser__show_title(&browser->b, sym->name); | ||
| 289 | return true; | ||
| 290 | } | ||
| 291 | |||
| 248 | static int annotate_browser__run(struct annotate_browser *self, int evidx, | 292 | static int annotate_browser__run(struct annotate_browser *self, int evidx, |
| 249 | void(*timer)(void *arg), | 293 | void(*timer)(void *arg), |
| 250 | void *arg, int delay_secs) | 294 | void *arg, int delay_secs) |
| @@ -321,54 +365,12 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, | |||
| 321 | continue; | 365 | continue; |
| 322 | case K_ENTER: | 366 | case K_ENTER: |
| 323 | case K_RIGHT: | 367 | case K_RIGHT: |
| 324 | if (self->selection == NULL) { | 368 | if (self->selection == NULL) |
| 325 | ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); | 369 | ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); |
| 326 | continue; | 370 | else if (self->selection->offset == -1) |
| 327 | } | ||
| 328 | |||
| 329 | if (self->selection->offset == -1) { | ||
| 330 | ui_helpline__puts("Actions are only available for assembly lines."); | 371 | ui_helpline__puts("Actions are only available for assembly lines."); |
| 331 | continue; | 372 | else if (!annotate_browser__callq(self, evidx, timer, arg, delay_secs)) |
| 332 | } else { | 373 | ui_helpline__puts("Actions are only available for the 'callq' instruction."); |
| 333 | char *s = strstr(self->selection->line, "callq "); | ||
| 334 | struct annotation *notes; | ||
| 335 | struct symbol *target; | ||
| 336 | u64 ip; | ||
| 337 | |||
| 338 | if (s == NULL) { | ||
| 339 | ui_helpline__puts("Actions are only available for the 'callq' instruction."); | ||
| 340 | continue; | ||
| 341 | } | ||
| 342 | |||
| 343 | s = strchr(s, ' '); | ||
| 344 | if (s++ == NULL) { | ||
| 345 | ui_helpline__puts("Invallid callq instruction."); | ||
| 346 | continue; | ||
| 347 | } | ||
| 348 | |||
| 349 | ip = strtoull(s, NULL, 16); | ||
| 350 | ip = ms->map->map_ip(ms->map, ip); | ||
| 351 | target = map__find_symbol(ms->map, ip, NULL); | ||
| 352 | if (target == NULL) { | ||
| 353 | ui_helpline__puts("The called function was not found."); | ||
| 354 | continue; | ||
| 355 | } | ||
| 356 | |||
| 357 | notes = symbol__annotation(target); | ||
| 358 | pthread_mutex_lock(¬es->lock); | ||
| 359 | |||
| 360 | if (notes->src == NULL && symbol__alloc_hist(target) < 0) { | ||
| 361 | pthread_mutex_unlock(¬es->lock); | ||
| 362 | ui__warning("Not enough memory for annotating '%s' symbol!\n", | ||
| 363 | target->name); | ||
| 364 | continue; | ||
| 365 | } | ||
| 366 | |||
| 367 | pthread_mutex_unlock(¬es->lock); | ||
| 368 | symbol__tui_annotate(target, ms->map, evidx, | ||
| 369 | timer, arg, delay_secs); | ||
| 370 | ui_browser__show_title(&self->b, sym->name); | ||
| 371 | } | ||
| 372 | continue; | 374 | continue; |
| 373 | case K_LEFT: | 375 | case K_LEFT: |
| 374 | case K_ESC: | 376 | case K_ESC: |
