diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/perf/util/machine.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 52e94902afb1..84390eecab06 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
| @@ -1381,6 +1381,34 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample, | |||
| 1381 | return mi; | 1381 | return mi; |
| 1382 | } | 1382 | } |
| 1383 | 1383 | ||
| 1384 | static int add_callchain_ip(struct thread *thread, | ||
| 1385 | struct symbol **parent, | ||
| 1386 | struct addr_location *root_al, | ||
| 1387 | int cpumode, | ||
| 1388 | u64 ip) | ||
| 1389 | { | ||
| 1390 | struct addr_location al; | ||
| 1391 | |||
| 1392 | al.filtered = 0; | ||
| 1393 | al.sym = NULL; | ||
| 1394 | thread__find_addr_location(thread, cpumode, MAP__FUNCTION, | ||
| 1395 | ip, &al); | ||
| 1396 | if (al.sym != NULL) { | ||
| 1397 | if (sort__has_parent && !*parent && | ||
| 1398 | symbol__match_regex(al.sym, &parent_regex)) | ||
| 1399 | *parent = al.sym; | ||
| 1400 | else if (have_ignore_callees && root_al && | ||
| 1401 | symbol__match_regex(al.sym, &ignore_callees_regex)) { | ||
| 1402 | /* Treat this symbol as the root, | ||
| 1403 | forgetting its callees. */ | ||
| 1404 | *root_al = al; | ||
| 1405 | callchain_cursor_reset(&callchain_cursor); | ||
| 1406 | } | ||
| 1407 | } | ||
| 1408 | |||
| 1409 | return callchain_cursor_append(&callchain_cursor, ip, al.map, al.sym); | ||
| 1410 | } | ||
| 1411 | |||
| 1384 | struct branch_info *sample__resolve_bstack(struct perf_sample *sample, | 1412 | struct branch_info *sample__resolve_bstack(struct perf_sample *sample, |
| 1385 | struct addr_location *al) | 1413 | struct addr_location *al) |
| 1386 | { | 1414 | { |
| @@ -1427,7 +1455,6 @@ static int thread__resolve_callchain_sample(struct thread *thread, | |||
| 1427 | 1455 | ||
| 1428 | for (i = 0; i < chain_nr; i++) { | 1456 | for (i = 0; i < chain_nr; i++) { |
| 1429 | u64 ip; | 1457 | u64 ip; |
| 1430 | struct addr_location al; | ||
| 1431 | 1458 | ||
| 1432 | if (callchain_param.order == ORDER_CALLEE) | 1459 | if (callchain_param.order == ORDER_CALLEE) |
| 1433 | j = i; | 1460 | j = i; |
| @@ -1464,24 +1491,10 @@ static int thread__resolve_callchain_sample(struct thread *thread, | |||
| 1464 | continue; | 1491 | continue; |
| 1465 | } | 1492 | } |
| 1466 | 1493 | ||
| 1467 | al.filtered = 0; | 1494 | err = add_callchain_ip(thread, parent, root_al, |
| 1468 | thread__find_addr_location(thread, cpumode, | 1495 | cpumode, ip); |
| 1469 | MAP__FUNCTION, ip, &al); | 1496 | if (err == -EINVAL) |
| 1470 | if (al.sym != NULL) { | 1497 | break; |
| 1471 | if (sort__has_parent && !*parent && | ||
| 1472 | symbol__match_regex(al.sym, &parent_regex)) | ||
| 1473 | *parent = al.sym; | ||
| 1474 | else if (have_ignore_callees && root_al && | ||
| 1475 | symbol__match_regex(al.sym, &ignore_callees_regex)) { | ||
| 1476 | /* Treat this symbol as the root, | ||
| 1477 | forgetting its callees. */ | ||
| 1478 | *root_al = al; | ||
| 1479 | callchain_cursor_reset(&callchain_cursor); | ||
| 1480 | } | ||
| 1481 | } | ||
| 1482 | |||
| 1483 | err = callchain_cursor_append(&callchain_cursor, | ||
| 1484 | ip, al.map, al.sym); | ||
| 1485 | if (err) | 1498 | if (err) |
| 1486 | return err; | 1499 | return err; |
| 1487 | } | 1500 | } |
