Use map__inlines to resolve inlined functions for every entry with
an symbol that should be added to a callchain.

Signed-off-by: Jonas Rabenstein <jonas.rabenst...@studium.uni-erlangen.de>
---
 tools/perf/util/machine.c | 115 ++++++++++++++++++++++++++++----------
 1 file changed, 87 insertions(+), 28 deletions(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index dce29c21e4ea..070d074482b4 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1908,6 +1908,91 @@ struct iterations {
        u64 cycles;
 };
 
+static int __add_callchain_location(struct callchain_cursor *cursor,
+                                   struct symbol **parent,
+                                   struct addr_location *root_al,
+                                   u64 addr, struct addr_location *al,
+                                   bool branch, struct branch_flags *flags,
+                                   u64 branch_from, struct iterations *iter)
+{
+       int nr_loop_iter = 0;
+       u64 iter_cycles = 0;
+
+       if (symbol_conf.hide_unresolved && al->sym == NULL)
+               return 0;
+
+       if (al->sym) {
+               if (perf_hpp_list.parent && !*parent &&
+                 symbol__match_regex(al->sym, &parent_regex))
+                       *parent = al->sym;
+               else if (have_ignore_callees && root_al &&
+                 symbol__match_regex(al->sym, &ignore_callees_regex)) {
+                       /* Treat this symbol as the root,
+                          forgetting its callees. */
+                       *root_al = *al;
+                       callchain_cursor_reset(cursor);
+               }
+       }
+
+       if (iter) {
+               nr_loop_iter = iter->nr_loop_iter;
+               iter_cycles = iter->cycles;
+       }
+       return callchain_cursor_append(cursor, addr, al->map, al->sym, branch,
+                                      flags, nr_loop_iter, iter_cycles,
+                                      branch_from, al->srcline);
+}
+
+static int __add_callchain_ip(struct callchain_cursor *cursor, u64 ip,
+                             struct addr_location *al, bool branch,
+                             struct branch_flags *flags, u64 branch_from,
+                             struct iterations *iter, struct symbol **parent,
+                             struct addr_location *root_al)
+{
+       struct inline_node *inline_node;
+       struct inline_list *inline_list;
+       const char *srcline;
+       struct symbol *symbol;
+       int err = 0;
+
+       al->srcline = callchain_srcline(al->map, al->sym, al->addr);
+       if (callchain_param.order == ORDER_CALLER)
+               err = __add_callchain_location(cursor, parent, root_al, ip, al,
+                                              branch, flags, branch_from, 
iter);
+       if (err || !al->map || !al->sym)
+               goto no_inline;
+
+       inline_node = map__inlines(al->map, ip, al->sym);
+       if (!inline_node || list_empty(&inline_node->val))
+               goto no_inline;
+
+       symbol = al->sym;
+       srcline = al->srcline;
+       list_for_each_entry(inline_list, &inline_node->val, list) {
+               if (inline_list->symbol == symbol)
+                       continue;
+               al->sym = inline_list->symbol;
+               al->srcline = inline_list->srcline;
+               err = __add_callchain_location(cursor, parent, root_al, ip,
+                                              al, branch, flags,
+                                              branch_from, iter);
+               if (err)
+                       break;
+       }
+
+       if (callchain_param.order == ORDER_CALLEE) {
+               al->srcline = srcline;
+               al->sym = symbol;
+       }
+
+no_inline:
+       if (!err && callchain_param.order == ORDER_CALLEE)
+               err = __add_callchain_location(cursor, parent, root_al, ip, al,
+                                              branch, flags, branch_from, 
iter);
+       return err;
+}
+
+
 static int add_callchain_ip(struct thread *thread,
                            struct callchain_cursor *cursor,
                            struct symbol **parent,
@@ -1920,9 +2005,6 @@ static int add_callchain_ip(struct thread *thread,
                            u64 branch_from)
 {
        struct addr_location al;
-       int nr_loop_iter = 0;
-       u64 iter_cycles = 0;
-       const char *srcline = NULL;
 
        al.filtered = 0;
        al.sym = NULL;
@@ -1955,31 +2037,8 @@ static int add_callchain_ip(struct thread *thread,
                thread__find_symbol(thread, *cpumode, ip, &al);
        }
 
-       if (al.sym != NULL) {
-               if (perf_hpp_list.parent && !*parent &&
-                   symbol__match_regex(al.sym, &parent_regex))
-                       *parent = al.sym;
-               else if (have_ignore_callees && root_al &&
-                 symbol__match_regex(al.sym, &ignore_callees_regex)) {
-                       /* Treat this symbol as the root,
-                          forgetting its callees. */
-                       *root_al = al;
-                       callchain_cursor_reset(cursor);
-               }
-       }
-
-       if (symbol_conf.hide_unresolved && al.sym == NULL)
-               return 0;
-
-       if (iter) {
-               nr_loop_iter = iter->nr_loop_iter;
-               iter_cycles = iter->cycles;
-       }
-
-       srcline = callchain_srcline(al.map, al.sym, al.addr);
-       return callchain_cursor_append(cursor, ip, al.map, al.sym,
-                                      branch, flags, nr_loop_iter,
-                                      iter_cycles, branch_from, srcline);
+       return __add_callchain_ip(cursor, ip, &al, branch, flags, branch_from,
+                                 iter, parent, root_al);
 }
 
 struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
-- 
2.19.2

Reply via email to