aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2011-08-14 05:48:29 -0400
committerIngo Molnar <mingo@elte.hu>2011-08-14 05:48:29 -0400
commitbdc2209fd246820de2816691ac0e82600885e1a8 (patch)
tree34dca4b8f1a94d1a4b6a79cff6931e8284e27718 /tools
parenteeca7360f756f7e36e846f35018df20808c7ef63 (diff)
parent3f4460a28fb2f73df6c32c3a305797abc01c0f9c (diff)
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-probe.c14
-rw-r--r--tools/perf/util/dwarf-aux.c210
-rw-r--r--tools/perf/util/dwarf-aux.h11
-rw-r--r--tools/perf/util/header.c11
-rw-r--r--tools/perf/util/probe-finder.c231
-rw-r--r--tools/perf/util/probe-finder.h2
-rw-r--r--tools/perf/util/symbol.c59
-rw-r--r--tools/perf/util/symbol.h1
-rw-r--r--tools/perf/util/ui/browsers/top.c1
9 files changed, 403 insertions, 137 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 5f2a5c7046df..710ae3d0a489 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -134,10 +134,18 @@ static int opt_show_lines(const struct option *opt __used,
134{ 134{
135 int ret = 0; 135 int ret = 0;
136 136
137 if (str) 137 if (!str)
138 ret = parse_line_range_desc(str, &params.line_range); 138 return 0;
139 INIT_LIST_HEAD(&params.line_range.line_list); 139
140 if (params.show_lines) {
141 pr_warning("Warning: more than one --line options are"
142 " detected. Only the first one is valid.\n");
143 return 0;
144 }
145
140 params.show_lines = true; 146 params.show_lines = true;
147 ret = parse_line_range_desc(str, &params.line_range);
148 INIT_LIST_HEAD(&params.line_range.line_list);
141 149
142 return ret; 150 return ret;
143} 151}
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index fddf40f30d3e..ee51e9b4dc09 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -96,6 +96,39 @@ int cu_find_lineinfo(Dwarf_Die *cu_die, unsigned long addr,
96 return *lineno ?: -ENOENT; 96 return *lineno ?: -ENOENT;
97} 97}
98 98
99static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data);
100
101/**
102 * cu_walk_functions_at - Walk on function DIEs at given address
103 * @cu_die: A CU DIE
104 * @addr: An address
105 * @callback: A callback which called with found DIEs
106 * @data: A user data
107 *
108 * Walk on function DIEs at given @addr in @cu_die. Passed DIEs
109 * should be subprogram or inlined-subroutines.
110 */
111int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
112 int (*callback)(Dwarf_Die *, void *), void *data)
113{
114 Dwarf_Die die_mem;
115 Dwarf_Die *sc_die;
116 int ret = -ENOENT;
117
118 /* Inlined function could be recursive. Trace it until fail */
119 for (sc_die = die_find_realfunc(cu_die, addr, &die_mem);
120 sc_die != NULL;
121 sc_die = die_find_child(sc_die, __die_find_inline_cb, &addr,
122 &die_mem)) {
123 ret = callback(sc_die, data);
124 if (ret)
125 break;
126 }
127
128 return ret;
129
130}
131
99/** 132/**
100 * die_compare_name - Compare diename and tname 133 * die_compare_name - Compare diename and tname
101 * @dw_die: a DIE 134 * @dw_die: a DIE
@@ -198,6 +231,19 @@ static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name,
198 return 0; 231 return 0;
199} 232}
200 233
234/* Get attribute and translate it as a sdata */
235static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name,
236 Dwarf_Sword *result)
237{
238 Dwarf_Attribute attr;
239
240 if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
241 dwarf_formsdata(&attr, result) != 0)
242 return -ENOENT;
243
244 return 0;
245}
246
201/** 247/**
202 * die_is_signed_type - Check whether a type DIE is signed or not 248 * die_is_signed_type - Check whether a type DIE is signed or not
203 * @tp_die: a DIE of a type 249 * @tp_die: a DIE of a type
@@ -250,6 +296,50 @@ int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
250 return 0; 296 return 0;
251} 297}
252 298
299/* Get the call file index number in CU DIE */
300static int die_get_call_fileno(Dwarf_Die *in_die)
301{
302 Dwarf_Sword idx;
303
304 if (die_get_attr_sdata(in_die, DW_AT_call_file, &idx) == 0)
305 return (int)idx;
306 else
307 return -ENOENT;
308}
309
310/* Get the declared file index number in CU DIE */
311static int die_get_decl_fileno(Dwarf_Die *pdie)
312{
313 Dwarf_Sword idx;
314
315 if (die_get_attr_sdata(pdie, DW_AT_decl_file, &idx) == 0)
316 return (int)idx;
317 else
318 return -ENOENT;
319}
320
321/**
322 * die_get_call_file - Get callsite file name of inlined function instance
323 * @in_die: a DIE of an inlined function instance
324 *
325 * Get call-site file name of @in_die. This means from which file the inline
326 * function is called.
327 */
328const char *die_get_call_file(Dwarf_Die *in_die)
329{
330 Dwarf_Die cu_die;
331 Dwarf_Files *files;
332 int idx;
333
334 idx = die_get_call_fileno(in_die);
335 if (idx < 0 || !dwarf_diecu(in_die, &cu_die, NULL, NULL) ||
336 dwarf_getsrcfiles(&cu_die, &files, NULL) != 0)
337 return NULL;
338
339 return dwarf_filesrc(files, idx, NULL, NULL);
340}
341
342
253/** 343/**
254 * die_find_child - Generic DIE search function in DIE tree 344 * die_find_child - Generic DIE search function in DIE tree
255 * @rt_die: a root DIE 345 * @rt_die: a root DIE
@@ -374,9 +464,78 @@ Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
374 return die_mem; 464 return die_mem;
375} 465}
376 466
467struct __instance_walk_param {
468 void *addr;
469 int (*callback)(Dwarf_Die *, void *);
470 void *data;
471 int retval;
472};
473
474static int __die_walk_instances_cb(Dwarf_Die *inst, void *data)
475{
476 struct __instance_walk_param *iwp = data;
477 Dwarf_Attribute attr_mem;
478 Dwarf_Die origin_mem;
479 Dwarf_Attribute *attr;
480 Dwarf_Die *origin;
481 int tmp;
482
483 attr = dwarf_attr(inst, DW_AT_abstract_origin, &attr_mem);
484 if (attr == NULL)
485 return DIE_FIND_CB_CONTINUE;
486
487 origin = dwarf_formref_die(attr, &origin_mem);
488 if (origin == NULL || origin->addr != iwp->addr)
489 return DIE_FIND_CB_CONTINUE;
490
491 /* Ignore redundant instances */
492 if (dwarf_tag(inst) == DW_TAG_inlined_subroutine) {
493 dwarf_decl_line(origin, &tmp);
494 if (die_get_call_lineno(inst) == tmp) {
495 tmp = die_get_decl_fileno(origin);
496 if (die_get_call_fileno(inst) == tmp)
497 return DIE_FIND_CB_CONTINUE;
498 }
499 }
500
501 iwp->retval = iwp->callback(inst, iwp->data);
502
503 return (iwp->retval) ? DIE_FIND_CB_END : DIE_FIND_CB_CONTINUE;
504}
505
506/**
507 * die_walk_instances - Walk on instances of given DIE
508 * @or_die: an abstract original DIE
509 * @callback: a callback function which is called with instance DIE
510 * @data: user data
511 *
512 * Walk on the instances of give @in_die. @in_die must be an inlined function
513 * declartion. This returns the return value of @callback if it returns
514 * non-zero value, or -ENOENT if there is no instance.
515 */
516int die_walk_instances(Dwarf_Die *or_die, int (*callback)(Dwarf_Die *, void *),
517 void *data)
518{
519 Dwarf_Die cu_die;
520 Dwarf_Die die_mem;
521 struct __instance_walk_param iwp = {
522 .addr = or_die->addr,
523 .callback = callback,
524 .data = data,
525 .retval = -ENOENT,
526 };
527
528 if (dwarf_diecu(or_die, &cu_die, NULL, NULL) == NULL)
529 return -ENOENT;
530
531 die_find_child(&cu_die, __die_walk_instances_cb, &iwp, &die_mem);
532
533 return iwp.retval;
534}
535
377/* Line walker internal parameters */ 536/* Line walker internal parameters */
378struct __line_walk_param { 537struct __line_walk_param {
379 const char *fname; 538 bool recursive;
380 line_walk_callback_t callback; 539 line_walk_callback_t callback;
381 void *data; 540 void *data;
382 int retval; 541 int retval;
@@ -385,39 +544,56 @@ struct __line_walk_param {
385static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data) 544static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data)
386{ 545{
387 struct __line_walk_param *lw = data; 546 struct __line_walk_param *lw = data;
388 Dwarf_Addr addr; 547 Dwarf_Addr addr = 0;
548 const char *fname;
389 int lineno; 549 int lineno;
390 550
391 if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) { 551 if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) {
552 fname = die_get_call_file(in_die);
392 lineno = die_get_call_lineno(in_die); 553 lineno = die_get_call_lineno(in_die);
393 if (lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) { 554 if (fname && lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) {
394 lw->retval = lw->callback(lw->fname, lineno, addr, 555 lw->retval = lw->callback(fname, lineno, addr, lw->data);
395 lw->data);
396 if (lw->retval != 0) 556 if (lw->retval != 0)
397 return DIE_FIND_CB_END; 557 return DIE_FIND_CB_END;
398 } 558 }
399 } 559 }
400 return DIE_FIND_CB_SIBLING; 560 if (!lw->recursive)
561 /* Don't need to search recursively */
562 return DIE_FIND_CB_SIBLING;
563
564 if (addr) {
565 fname = dwarf_decl_file(in_die);
566 if (fname && dwarf_decl_line(in_die, &lineno) == 0) {
567 lw->retval = lw->callback(fname, lineno, addr, lw->data);
568 if (lw->retval != 0)
569 return DIE_FIND_CB_END;
570 }
571 }
572
573 /* Continue to search nested inlined function call-sites */
574 return DIE_FIND_CB_CONTINUE;
401} 575}
402 576
403/* Walk on lines of blocks included in given DIE */ 577/* Walk on lines of blocks included in given DIE */
404static int __die_walk_funclines(Dwarf_Die *sp_die, 578static int __die_walk_funclines(Dwarf_Die *sp_die, bool recursive,
405 line_walk_callback_t callback, void *data) 579 line_walk_callback_t callback, void *data)
406{ 580{
407 struct __line_walk_param lw = { 581 struct __line_walk_param lw = {
582 .recursive = recursive,
408 .callback = callback, 583 .callback = callback,
409 .data = data, 584 .data = data,
410 .retval = 0, 585 .retval = 0,
411 }; 586 };
412 Dwarf_Die die_mem; 587 Dwarf_Die die_mem;
413 Dwarf_Addr addr; 588 Dwarf_Addr addr;
589 const char *fname;
414 int lineno; 590 int lineno;
415 591
416 /* Handle function declaration line */ 592 /* Handle function declaration line */
417 lw.fname = dwarf_decl_file(sp_die); 593 fname = dwarf_decl_file(sp_die);
418 if (lw.fname && dwarf_decl_line(sp_die, &lineno) == 0 && 594 if (fname && dwarf_decl_line(sp_die, &lineno) == 0 &&
419 dwarf_entrypc(sp_die, &addr) == 0) { 595 dwarf_entrypc(sp_die, &addr) == 0) {
420 lw.retval = callback(lw.fname, lineno, addr, data); 596 lw.retval = callback(fname, lineno, addr, data);
421 if (lw.retval != 0) 597 if (lw.retval != 0)
422 goto done; 598 goto done;
423 } 599 }
@@ -430,7 +606,7 @@ static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data)
430{ 606{
431 struct __line_walk_param *lw = data; 607 struct __line_walk_param *lw = data;
432 608
433 lw->retval = __die_walk_funclines(sp_die, lw->callback, lw->data); 609 lw->retval = __die_walk_funclines(sp_die, true, lw->callback, lw->data);
434 if (lw->retval != 0) 610 if (lw->retval != 0)
435 return DWARF_CB_ABORT; 611 return DWARF_CB_ABORT;
436 612
@@ -439,7 +615,7 @@ static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data)
439 615
440/** 616/**
441 * die_walk_lines - Walk on lines inside given DIE 617 * die_walk_lines - Walk on lines inside given DIE
442 * @rt_die: a root DIE (CU or subprogram) 618 * @rt_die: a root DIE (CU, subprogram or inlined_subroutine)
443 * @callback: callback routine 619 * @callback: callback routine
444 * @data: user data 620 * @data: user data
445 * 621 *
@@ -460,12 +636,12 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)
460 size_t nlines, i; 636 size_t nlines, i;
461 637
462 /* Get the CU die */ 638 /* Get the CU die */
463 if (dwarf_tag(rt_die) == DW_TAG_subprogram) 639 if (dwarf_tag(rt_die) != DW_TAG_compile_unit)
464 cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL); 640 cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL);
465 else 641 else
466 cu_die = rt_die; 642 cu_die = rt_die;
467 if (!cu_die) { 643 if (!cu_die) {
468 pr_debug2("Failed to get CU from subprogram\n"); 644 pr_debug2("Failed to get CU from given DIE.\n");
469 return -EINVAL; 645 return -EINVAL;
470 } 646 }
471 647
@@ -509,7 +685,11 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)
509 * subroutines. We have to check functions list or given function. 685 * subroutines. We have to check functions list or given function.
510 */ 686 */
511 if (rt_die != cu_die) 687 if (rt_die != cu_die)
512 ret = __die_walk_funclines(rt_die, callback, data); 688 /*
689 * Don't need walk functions recursively, because nested
690 * inlined functions don't have lines of the specified DIE.
691 */
692 ret = __die_walk_funclines(rt_die, false, callback, data);
513 else { 693 else {
514 struct __line_walk_param param = { 694 struct __line_walk_param param = {
515 .callback = callback, 695 .callback = callback,
diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h
index bc3b21167e70..6ce1717784b7 100644
--- a/tools/perf/util/dwarf-aux.h
+++ b/tools/perf/util/dwarf-aux.h
@@ -34,12 +34,19 @@ extern const char *cu_get_comp_dir(Dwarf_Die *cu_die);
34extern int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr, 34extern int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
35 const char **fname, int *lineno); 35 const char **fname, int *lineno);
36 36
37/* Walk on funcitons at given address */
38extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
39 int (*callback)(Dwarf_Die *, void *), void *data);
40
37/* Compare diename and tname */ 41/* Compare diename and tname */
38extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname); 42extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname);
39 43
40/* Get callsite line number of inline-function instance */ 44/* Get callsite line number of inline-function instance */
41extern int die_get_call_lineno(Dwarf_Die *in_die); 45extern int die_get_call_lineno(Dwarf_Die *in_die);
42 46
47/* Get callsite file name of inlined function instance */
48extern const char *die_get_call_file(Dwarf_Die *in_die);
49
43/* Get type die */ 50/* Get type die */
44extern Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); 51extern Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);
45 52
@@ -73,6 +80,10 @@ extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
73extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 80extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
74 Dwarf_Die *die_mem); 81 Dwarf_Die *die_mem);
75 82
83/* Walk on the instances of given DIE */
84extern int die_walk_instances(Dwarf_Die *in_die,
85 int (*callback)(Dwarf_Die *, void *), void *data);
86
76/* Walker on lines (Note: line number will not be sorted) */ 87/* Walker on lines (Note: line number will not be sorted) */
77typedef int (* line_walk_callback_t) (const char *fname, int lineno, 88typedef int (* line_walk_callback_t) (const char *fname, int lineno,
78 Dwarf_Addr addr, void *data); 89 Dwarf_Addr addr, void *data);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index d4f3101773db..b6c1ad123ca9 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -726,7 +726,16 @@ static int perf_header__read_build_ids_abi_quirk(struct perf_header *header,
726 return -1; 726 return -1;
727 727
728 bev.header = old_bev.header; 728 bev.header = old_bev.header;
729 bev.pid = 0; 729
730 /*
731 * As the pid is the missing value, we need to fill
732 * it properly. The header.misc value give us nice hint.
733 */
734 bev.pid = HOST_KERNEL_ID;
735 if (bev.header.misc == PERF_RECORD_MISC_GUEST_USER ||
736 bev.header.misc == PERF_RECORD_MISC_GUEST_KERNEL)
737 bev.pid = DEFAULT_GUEST_KERNEL_ID;
738
730 memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id)); 739 memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id));
731 __event_process_build_id(&bev, filename, session); 740 __event_process_build_id(&bev, filename, session);
732 741
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 3e44a3e36519..555fc3864b90 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -612,12 +612,12 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
612 return ret; 612 return ret;
613} 613}
614 614
615/* Find a variable in a subprogram die */ 615/* Find a variable in a scope DIE */
616static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf) 616static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
617{ 617{
618 Dwarf_Die vr_die, *scopes; 618 Dwarf_Die vr_die;
619 char buf[32], *ptr; 619 char buf[32], *ptr;
620 int ret, nscopes; 620 int ret = 0;
621 621
622 if (!is_c_varname(pf->pvar->var)) { 622 if (!is_c_varname(pf->pvar->var)) {
623 /* Copy raw parameters */ 623 /* Copy raw parameters */
@@ -652,30 +652,16 @@ static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
652 if (pf->tvar->name == NULL) 652 if (pf->tvar->name == NULL)
653 return -ENOMEM; 653 return -ENOMEM;
654 654
655 pr_debug("Searching '%s' variable in context.\n", 655 pr_debug("Searching '%s' variable in context.\n", pf->pvar->var);
656 pf->pvar->var);
657 /* Search child die for local variables and parameters. */ 656 /* Search child die for local variables and parameters. */
658 if (die_find_variable_at(sp_die, pf->pvar->var, pf->addr, &vr_die)) 657 if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) {
659 ret = convert_variable(&vr_die, pf); 658 /* Search again in global variables */
660 else { 659 if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die))
661 /* Search upper class */ 660 ret = -ENOENT;
662 nscopes = dwarf_getscopes_die(sp_die, &scopes);
663 while (nscopes-- > 1) {
664 pr_debug("Searching variables in %s\n",
665 dwarf_diename(&scopes[nscopes]));
666 /* We should check this scope, so give dummy address */
667 if (die_find_variable_at(&scopes[nscopes],
668 pf->pvar->var, 0,
669 &vr_die)) {
670 ret = convert_variable(&vr_die, pf);
671 goto found;
672 }
673 }
674 if (scopes)
675 free(scopes);
676 ret = -ENOENT;
677 } 661 }
678found: 662 if (ret == 0)
663 ret = convert_variable(&vr_die, pf);
664
679 if (ret < 0) 665 if (ret < 0)
680 pr_warning("Failed to find '%s' in this function.\n", 666 pr_warning("Failed to find '%s' in this function.\n",
681 pf->pvar->var); 667 pf->pvar->var);
@@ -718,26 +704,30 @@ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr,
718 return 0; 704 return 0;
719} 705}
720 706
721/* Call probe_finder callback with real subprogram DIE */ 707/* Call probe_finder callback with scope DIE */
722static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf) 708static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf)
723{ 709{
724 Dwarf_Die die_mem;
725 Dwarf_Attribute fb_attr; 710 Dwarf_Attribute fb_attr;
726 size_t nops; 711 size_t nops;
727 int ret; 712 int ret;
728 713
729 /* If no real subprogram, find a real one */ 714 if (!sc_die) {
730 if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) { 715 pr_err("Caller must pass a scope DIE. Program error.\n");
731 sp_die = die_find_realfunc(&pf->cu_die, pf->addr, &die_mem); 716 return -EINVAL;
732 if (!sp_die) { 717 }
718
719 /* If not a real subprogram, find a real one */
720 if (dwarf_tag(sc_die) != DW_TAG_subprogram) {
721 if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) {
733 pr_warning("Failed to find probe point in any " 722 pr_warning("Failed to find probe point in any "
734 "functions.\n"); 723 "functions.\n");
735 return -ENOENT; 724 return -ENOENT;
736 } 725 }
737 } 726 } else
727 memcpy(&pf->sp_die, sc_die, sizeof(Dwarf_Die));
738 728
739 /* Get the frame base attribute/ops */ 729 /* Get the frame base attribute/ops from subprogram */
740 dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr); 730 dwarf_attr(&pf->sp_die, DW_AT_frame_base, &fb_attr);
741 ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1); 731 ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
742 if (ret <= 0 || nops == 0) { 732 if (ret <= 0 || nops == 0) {
743 pf->fb_ops = NULL; 733 pf->fb_ops = NULL;
@@ -755,7 +745,7 @@ static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf)
755 } 745 }
756 746
757 /* Call finder's callback handler */ 747 /* Call finder's callback handler */
758 ret = pf->callback(sp_die, pf); 748 ret = pf->callback(sc_die, pf);
759 749
760 /* *pf->fb_ops will be cached in libdw. Don't free it. */ 750 /* *pf->fb_ops will be cached in libdw. Don't free it. */
761 pf->fb_ops = NULL; 751 pf->fb_ops = NULL;
@@ -763,17 +753,82 @@ static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf)
763 return ret; 753 return ret;
764} 754}
765 755
756struct find_scope_param {
757 const char *function;
758 const char *file;
759 int line;
760 int diff;
761 Dwarf_Die *die_mem;
762 bool found;
763};
764
765static int find_best_scope_cb(Dwarf_Die *fn_die, void *data)
766{
767 struct find_scope_param *fsp = data;
768 const char *file;
769 int lno;
770
771 /* Skip if declared file name does not match */
772 if (fsp->file) {
773 file = dwarf_decl_file(fn_die);
774 if (!file || strcmp(fsp->file, file) != 0)
775 return 0;
776 }
777 /* If the function name is given, that's what user expects */
778 if (fsp->function) {
779 if (die_compare_name(fn_die, fsp->function)) {
780 memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
781 fsp->found = true;
782 return 1;
783 }
784 } else {
785 /* With the line number, find the nearest declared DIE */
786 dwarf_decl_line(fn_die, &lno);
787 if (lno < fsp->line && fsp->diff > fsp->line - lno) {
788 /* Keep a candidate and continue */
789 fsp->diff = fsp->line - lno;
790 memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
791 fsp->found = true;
792 }
793 }
794 return 0;
795}
796
797/* Find an appropriate scope fits to given conditions */
798static Dwarf_Die *find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem)
799{
800 struct find_scope_param fsp = {
801 .function = pf->pev->point.function,
802 .file = pf->fname,
803 .line = pf->lno,
804 .diff = INT_MAX,
805 .die_mem = die_mem,
806 .found = false,
807 };
808
809 cu_walk_functions_at(&pf->cu_die, pf->addr, find_best_scope_cb, &fsp);
810
811 return fsp.found ? die_mem : NULL;
812}
813
766static int probe_point_line_walker(const char *fname, int lineno, 814static int probe_point_line_walker(const char *fname, int lineno,
767 Dwarf_Addr addr, void *data) 815 Dwarf_Addr addr, void *data)
768{ 816{
769 struct probe_finder *pf = data; 817 struct probe_finder *pf = data;
818 Dwarf_Die *sc_die, die_mem;
770 int ret; 819 int ret;
771 820
772 if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0) 821 if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0)
773 return 0; 822 return 0;
774 823
775 pf->addr = addr; 824 pf->addr = addr;
776 ret = call_probe_finder(NULL, pf); 825 sc_die = find_best_scope(pf, &die_mem);
826 if (!sc_die) {
827 pr_warning("Failed to find scope of probe point.\n");
828 return -ENOENT;
829 }
830
831 ret = call_probe_finder(sc_die, pf);
777 832
778 /* Continue if no error, because the line will be in inline function */ 833 /* Continue if no error, because the line will be in inline function */
779 return ret < 0 ? ret : 0; 834 return ret < 0 ? ret : 0;
@@ -827,6 +882,7 @@ static int probe_point_lazy_walker(const char *fname, int lineno,
827 Dwarf_Addr addr, void *data) 882 Dwarf_Addr addr, void *data)
828{ 883{
829 struct probe_finder *pf = data; 884 struct probe_finder *pf = data;
885 Dwarf_Die *sc_die, die_mem;
830 int ret; 886 int ret;
831 887
832 if (!line_list__has_line(&pf->lcache, lineno) || 888 if (!line_list__has_line(&pf->lcache, lineno) ||
@@ -836,7 +892,14 @@ static int probe_point_lazy_walker(const char *fname, int lineno,
836 pr_debug("Probe line found: line:%d addr:0x%llx\n", 892 pr_debug("Probe line found: line:%d addr:0x%llx\n",
837 lineno, (unsigned long long)addr); 893 lineno, (unsigned long long)addr);
838 pf->addr = addr; 894 pf->addr = addr;
839 ret = call_probe_finder(NULL, pf); 895 pf->lno = lineno;
896 sc_die = find_best_scope(pf, &die_mem);
897 if (!sc_die) {
898 pr_warning("Failed to find scope of probe point.\n");
899 return -ENOENT;
900 }
901
902 ret = call_probe_finder(sc_die, pf);
840 903
841 /* 904 /*
842 * Continue if no error, because the lazy pattern will match 905 * Continue if no error, because the lazy pattern will match
@@ -861,42 +924,39 @@ static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
861 return die_walk_lines(sp_die, probe_point_lazy_walker, pf); 924 return die_walk_lines(sp_die, probe_point_lazy_walker, pf);
862} 925}
863 926
864/* Callback parameter with return value */
865struct dwarf_callback_param {
866 void *data;
867 int retval;
868};
869
870static int probe_point_inline_cb(Dwarf_Die *in_die, void *data) 927static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
871{ 928{
872 struct dwarf_callback_param *param = data; 929 struct probe_finder *pf = data;
873 struct probe_finder *pf = param->data;
874 struct perf_probe_point *pp = &pf->pev->point; 930 struct perf_probe_point *pp = &pf->pev->point;
875 Dwarf_Addr addr; 931 Dwarf_Addr addr;
932 int ret;
876 933
877 if (pp->lazy_line) 934 if (pp->lazy_line)
878 param->retval = find_probe_point_lazy(in_die, pf); 935 ret = find_probe_point_lazy(in_die, pf);
879 else { 936 else {
880 /* Get probe address */ 937 /* Get probe address */
881 if (dwarf_entrypc(in_die, &addr) != 0) { 938 if (dwarf_entrypc(in_die, &addr) != 0) {
882 pr_warning("Failed to get entry address of %s.\n", 939 pr_warning("Failed to get entry address of %s.\n",
883 dwarf_diename(in_die)); 940 dwarf_diename(in_die));
884 param->retval = -ENOENT; 941 return -ENOENT;
885 return DWARF_CB_ABORT;
886 } 942 }
887 pf->addr = addr; 943 pf->addr = addr;
888 pf->addr += pp->offset; 944 pf->addr += pp->offset;
889 pr_debug("found inline addr: 0x%jx\n", 945 pr_debug("found inline addr: 0x%jx\n",
890 (uintmax_t)pf->addr); 946 (uintmax_t)pf->addr);
891 947
892 param->retval = call_probe_finder(in_die, pf); 948 ret = call_probe_finder(in_die, pf);
893 if (param->retval < 0)
894 return DWARF_CB_ABORT;
895 } 949 }
896 950
897 return DWARF_CB_OK; 951 return ret;
898} 952}
899 953
954/* Callback parameter with return value for libdw */
955struct dwarf_callback_param {
956 void *data;
957 int retval;
958};
959
900/* Search function from function name */ 960/* Search function from function name */
901static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) 961static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
902{ 962{
@@ -933,14 +993,10 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
933 /* TODO: Check the address in this function */ 993 /* TODO: Check the address in this function */
934 param->retval = call_probe_finder(sp_die, pf); 994 param->retval = call_probe_finder(sp_die, pf);
935 } 995 }
936 } else { 996 } else
937 struct dwarf_callback_param _param = {.data = (void *)pf,
938 .retval = 0};
939 /* Inlined function: search instances */ 997 /* Inlined function: search instances */
940 dwarf_func_inline_instances(sp_die, probe_point_inline_cb, 998 param->retval = die_walk_instances(sp_die,
941 &_param); 999 probe_point_inline_cb, (void *)pf);
942 param->retval = _param.retval;
943 }
944 1000
945 return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */ 1001 return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */
946} 1002}
@@ -1060,7 +1116,7 @@ found:
1060} 1116}
1061 1117
1062/* Add a found probe point into trace event list */ 1118/* Add a found probe point into trace event list */
1063static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf) 1119static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
1064{ 1120{
1065 struct trace_event_finder *tf = 1121 struct trace_event_finder *tf =
1066 container_of(pf, struct trace_event_finder, pf); 1122 container_of(pf, struct trace_event_finder, pf);
@@ -1075,8 +1131,9 @@ static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf)
1075 } 1131 }
1076 tev = &tf->tevs[tf->ntevs++]; 1132 tev = &tf->tevs[tf->ntevs++];
1077 1133
1078 ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe, 1134 /* Trace point should be converted from subprogram DIE */
1079 &tev->point); 1135 ret = convert_to_trace_point(&pf->sp_die, pf->addr,
1136 pf->pev->point.retprobe, &tev->point);
1080 if (ret < 0) 1137 if (ret < 0)
1081 return ret; 1138 return ret;
1082 1139
@@ -1091,7 +1148,8 @@ static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf)
1091 for (i = 0; i < pf->pev->nargs; i++) { 1148 for (i = 0; i < pf->pev->nargs; i++) {
1092 pf->pvar = &pf->pev->args[i]; 1149 pf->pvar = &pf->pev->args[i];
1093 pf->tvar = &tev->args[i]; 1150 pf->tvar = &tev->args[i];
1094 ret = find_variable(sp_die, pf); 1151 /* Variable should be found from scope DIE */
1152 ret = find_variable(sc_die, pf);
1095 if (ret != 0) 1153 if (ret != 0)
1096 return ret; 1154 return ret;
1097 } 1155 }
@@ -1159,13 +1217,13 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1159} 1217}
1160 1218
1161/* Add a found vars into available variables list */ 1219/* Add a found vars into available variables list */
1162static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf) 1220static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
1163{ 1221{
1164 struct available_var_finder *af = 1222 struct available_var_finder *af =
1165 container_of(pf, struct available_var_finder, pf); 1223 container_of(pf, struct available_var_finder, pf);
1166 struct variable_list *vl; 1224 struct variable_list *vl;
1167 Dwarf_Die die_mem, *scopes = NULL; 1225 Dwarf_Die die_mem;
1168 int ret, nscopes; 1226 int ret;
1169 1227
1170 /* Check number of tevs */ 1228 /* Check number of tevs */
1171 if (af->nvls == af->max_vls) { 1229 if (af->nvls == af->max_vls) {
@@ -1174,8 +1232,9 @@ static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf)
1174 } 1232 }
1175 vl = &af->vls[af->nvls++]; 1233 vl = &af->vls[af->nvls++];
1176 1234
1177 ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe, 1235 /* Trace point should be converted from subprogram DIE */
1178 &vl->point); 1236 ret = convert_to_trace_point(&pf->sp_die, pf->addr,
1237 pf->pev->point.retprobe, &vl->point);
1179 if (ret < 0) 1238 if (ret < 0)
1180 return ret; 1239 return ret;
1181 1240
@@ -1187,19 +1246,14 @@ static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf)
1187 if (vl->vars == NULL) 1246 if (vl->vars == NULL)
1188 return -ENOMEM; 1247 return -ENOMEM;
1189 af->child = true; 1248 af->child = true;
1190 die_find_child(sp_die, collect_variables_cb, (void *)af, &die_mem); 1249 die_find_child(sc_die, collect_variables_cb, (void *)af, &die_mem);
1191 1250
1192 /* Find external variables */ 1251 /* Find external variables */
1193 if (!af->externs) 1252 if (!af->externs)
1194 goto out; 1253 goto out;
1195 /* Don't need to search child DIE for externs. */ 1254 /* Don't need to search child DIE for externs. */
1196 af->child = false; 1255 af->child = false;
1197 nscopes = dwarf_getscopes_die(sp_die, &scopes); 1256 die_find_child(&pf->cu_die, collect_variables_cb, (void *)af, &die_mem);
1198 while (nscopes-- > 1)
1199 die_find_child(&scopes[nscopes], collect_variables_cb,
1200 (void *)af, &die_mem);
1201 if (scopes)
1202 free(scopes);
1203 1257
1204out: 1258out:
1205 if (strlist__empty(vl->vars)) { 1259 if (strlist__empty(vl->vars)) {
@@ -1391,10 +1445,14 @@ static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
1391 1445
1392static int line_range_inline_cb(Dwarf_Die *in_die, void *data) 1446static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
1393{ 1447{
1394 struct dwarf_callback_param *param = data; 1448 find_line_range_by_line(in_die, data);
1395 1449
1396 param->retval = find_line_range_by_line(in_die, param->data); 1450 /*
1397 return DWARF_CB_ABORT; /* No need to find other instances */ 1451 * We have to check all instances of inlined function, because
1452 * some execution paths can be optimized out depends on the
1453 * function argument of instances
1454 */
1455 return 0;
1398} 1456}
1399 1457
1400/* Search function from function name */ 1458/* Search function from function name */
@@ -1422,15 +1480,10 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
1422 pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e); 1480 pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e);
1423 lr->start = lf->lno_s; 1481 lr->start = lf->lno_s;
1424 lr->end = lf->lno_e; 1482 lr->end = lf->lno_e;
1425 if (dwarf_func_inline(sp_die)) { 1483 if (dwarf_func_inline(sp_die))
1426 struct dwarf_callback_param _param; 1484 param->retval = die_walk_instances(sp_die,
1427 _param.data = (void *)lf; 1485 line_range_inline_cb, lf);
1428 _param.retval = 0; 1486 else
1429 dwarf_func_inline_instances(sp_die,
1430 line_range_inline_cb,
1431 &_param);
1432 param->retval = _param.retval;
1433 } else
1434 param->retval = find_line_range_by_line(sp_die, lf); 1487 param->retval = find_line_range_by_line(sp_die, lf);
1435 return DWARF_CB_ABORT; 1488 return DWARF_CB_ABORT;
1436 } 1489 }
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index c478b42a2473..1132c8f0ce89 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -57,7 +57,7 @@ struct probe_finder {
57 struct perf_probe_event *pev; /* Target probe event */ 57 struct perf_probe_event *pev; /* Target probe event */
58 58
59 /* Callback when a probe point is found */ 59 /* Callback when a probe point is found */
60 int (*callback)(Dwarf_Die *sp_die, struct probe_finder *pf); 60 int (*callback)(Dwarf_Die *sc_die, struct probe_finder *pf);
61 61
62 /* For function searching */ 62 /* For function searching */
63 int lno; /* Line number */ 63 int lno; /* Line number */
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index a8b53714542a..469c0264ed29 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1506,7 +1506,7 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1506 if (strncmp(dso->name, "/tmp/perf-", 10) == 0) { 1506 if (strncmp(dso->name, "/tmp/perf-", 10) == 0) {
1507 struct stat st; 1507 struct stat st;
1508 1508
1509 if (stat(dso->name, &st) < 0) 1509 if (lstat(dso->name, &st) < 0)
1510 return -1; 1510 return -1;
1511 1511
1512 if (st.st_uid && (st.st_uid != geteuid())) { 1512 if (st.st_uid && (st.st_uid != geteuid())) {
@@ -2181,27 +2181,22 @@ size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
2181 return ret; 2181 return ret;
2182} 2182}
2183 2183
2184struct dso *dso__new_kernel(const char *name) 2184static struct dso*
2185dso__kernel_findnew(struct machine *machine, const char *name,
2186 const char *short_name, int dso_type)
2185{ 2187{
2186 struct dso *dso = dso__new(name ?: "[kernel.kallsyms]"); 2188 /*
2187 2189 * The kernel dso could be created by build_id processing.
2188 if (dso != NULL) { 2190 */
2189 dso__set_short_name(dso, "[kernel]"); 2191 struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name);
2190 dso->kernel = DSO_TYPE_KERNEL;
2191 }
2192
2193 return dso;
2194}
2195 2192
2196static struct dso *dso__new_guest_kernel(struct machine *machine, 2193 /*
2197 const char *name) 2194 * We need to run this in all cases, since during the build_id
2198{ 2195 * processing we had no idea this was the kernel dso.
2199 char bf[PATH_MAX]; 2196 */
2200 struct dso *dso = dso__new(name ?: machine__mmap_name(machine, bf,
2201 sizeof(bf)));
2202 if (dso != NULL) { 2197 if (dso != NULL) {
2203 dso__set_short_name(dso, "[guest.kernel]"); 2198 dso__set_short_name(dso, short_name);
2204 dso->kernel = DSO_TYPE_GUEST_KERNEL; 2199 dso->kernel = dso_type;
2205 } 2200 }
2206 2201
2207 return dso; 2202 return dso;
@@ -2219,24 +2214,36 @@ void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
2219 dso->has_build_id = true; 2214 dso->has_build_id = true;
2220} 2215}
2221 2216
2222static struct dso *machine__create_kernel(struct machine *machine) 2217static struct dso *machine__get_kernel(struct machine *machine)
2223{ 2218{
2224 const char *vmlinux_name = NULL; 2219 const char *vmlinux_name = NULL;
2225 struct dso *kernel; 2220 struct dso *kernel;
2226 2221
2227 if (machine__is_host(machine)) { 2222 if (machine__is_host(machine)) {
2228 vmlinux_name = symbol_conf.vmlinux_name; 2223 vmlinux_name = symbol_conf.vmlinux_name;
2229 kernel = dso__new_kernel(vmlinux_name); 2224 if (!vmlinux_name)
2225 vmlinux_name = "[kernel.kallsyms]";
2226
2227 kernel = dso__kernel_findnew(machine, vmlinux_name,
2228 "[kernel]",
2229 DSO_TYPE_KERNEL);
2230 } else { 2230 } else {
2231 char bf[PATH_MAX];
2232
2231 if (machine__is_default_guest(machine)) 2233 if (machine__is_default_guest(machine))
2232 vmlinux_name = symbol_conf.default_guest_vmlinux_name; 2234 vmlinux_name = symbol_conf.default_guest_vmlinux_name;
2233 kernel = dso__new_guest_kernel(machine, vmlinux_name); 2235 if (!vmlinux_name)
2236 vmlinux_name = machine__mmap_name(machine, bf,
2237 sizeof(bf));
2238
2239 kernel = dso__kernel_findnew(machine, vmlinux_name,
2240 "[guest.kernel]",
2241 DSO_TYPE_GUEST_KERNEL);
2234 } 2242 }
2235 2243
2236 if (kernel != NULL) { 2244 if (kernel != NULL && (!kernel->has_build_id))
2237 dso__read_running_kernel_build_id(kernel, machine); 2245 dso__read_running_kernel_build_id(kernel, machine);
2238 dsos__add(&machine->kernel_dsos, kernel); 2246
2239 }
2240 return kernel; 2247 return kernel;
2241} 2248}
2242 2249
@@ -2340,7 +2347,7 @@ void machine__destroy_kernel_maps(struct machine *machine)
2340 2347
2341int machine__create_kernel_maps(struct machine *machine) 2348int machine__create_kernel_maps(struct machine *machine)
2342{ 2349{
2343 struct dso *kernel = machine__create_kernel(machine); 2350 struct dso *kernel = machine__get_kernel(machine);
2344 2351
2345 if (kernel == NULL || 2352 if (kernel == NULL ||
2346 __machine__create_kernel_maps(machine, kernel) < 0) 2353 __machine__create_kernel_maps(machine, kernel) < 0)
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 325ee36a9d29..4f377d92e75a 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -155,7 +155,6 @@ struct dso {
155}; 155};
156 156
157struct dso *dso__new(const char *name); 157struct dso *dso__new(const char *name);
158struct dso *dso__new_kernel(const char *name);
159void dso__delete(struct dso *dso); 158void dso__delete(struct dso *dso);
160 159
161int dso__name_len(const struct dso *dso); 160int dso__name_len(const struct dso *dso);
diff --git a/tools/perf/util/ui/browsers/top.c b/tools/perf/util/ui/browsers/top.c
index 5a06538532af..88403cf8396a 100644
--- a/tools/perf/util/ui/browsers/top.c
+++ b/tools/perf/util/ui/browsers/top.c
@@ -208,6 +208,5 @@ int perf_top__tui_browser(struct perf_top *top)
208 }, 208 },
209 }; 209 };
210 210
211 ui_helpline__push("Press <- or ESC to exit");
212 return perf_top_browser__run(&browser); 211 return perf_top_browser__run(&browser);
213} 212}