18c2ecf20Sopenharmony_ci#include <errno.h> 28c2ecf20Sopenharmony_ci#include <fcntl.h> 38c2ecf20Sopenharmony_ci#include <inttypes.h> 48c2ecf20Sopenharmony_ci#include <linux/kernel.h> 58c2ecf20Sopenharmony_ci#include <linux/types.h> 68c2ecf20Sopenharmony_ci#include <perf/cpumap.h> 78c2ecf20Sopenharmony_ci#include <sys/types.h> 88c2ecf20Sopenharmony_ci#include <sys/stat.h> 98c2ecf20Sopenharmony_ci#include <unistd.h> 108c2ecf20Sopenharmony_ci#include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */ 118c2ecf20Sopenharmony_ci#include <linux/perf_event.h> 128c2ecf20Sopenharmony_ci#include <linux/zalloc.h> 138c2ecf20Sopenharmony_ci#include "cpumap.h" 148c2ecf20Sopenharmony_ci#include "dso.h" 158c2ecf20Sopenharmony_ci#include "event.h" 168c2ecf20Sopenharmony_ci#include "debug.h" 178c2ecf20Sopenharmony_ci#include "hist.h" 188c2ecf20Sopenharmony_ci#include "machine.h" 198c2ecf20Sopenharmony_ci#include "sort.h" 208c2ecf20Sopenharmony_ci#include "string2.h" 218c2ecf20Sopenharmony_ci#include "strlist.h" 228c2ecf20Sopenharmony_ci#include "thread.h" 238c2ecf20Sopenharmony_ci#include "thread_map.h" 248c2ecf20Sopenharmony_ci#include "time-utils.h" 258c2ecf20Sopenharmony_ci#include <linux/ctype.h> 268c2ecf20Sopenharmony_ci#include "map.h" 278c2ecf20Sopenharmony_ci#include "util/namespaces.h" 288c2ecf20Sopenharmony_ci#include "symbol.h" 298c2ecf20Sopenharmony_ci#include "symbol/kallsyms.h" 308c2ecf20Sopenharmony_ci#include "asm/bug.h" 318c2ecf20Sopenharmony_ci#include "stat.h" 328c2ecf20Sopenharmony_ci#include "session.h" 338c2ecf20Sopenharmony_ci#include "bpf-event.h" 348c2ecf20Sopenharmony_ci#include "print_binary.h" 358c2ecf20Sopenharmony_ci#include "tool.h" 368c2ecf20Sopenharmony_ci#include "../perf.h" 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistatic const char *perf_event__names[] = { 398c2ecf20Sopenharmony_ci [0] = "TOTAL", 408c2ecf20Sopenharmony_ci [PERF_RECORD_MMAP] = "MMAP", 418c2ecf20Sopenharmony_ci [PERF_RECORD_MMAP2] = "MMAP2", 428c2ecf20Sopenharmony_ci [PERF_RECORD_LOST] = "LOST", 438c2ecf20Sopenharmony_ci [PERF_RECORD_COMM] = "COMM", 448c2ecf20Sopenharmony_ci [PERF_RECORD_EXIT] = "EXIT", 458c2ecf20Sopenharmony_ci [PERF_RECORD_THROTTLE] = "THROTTLE", 468c2ecf20Sopenharmony_ci [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE", 478c2ecf20Sopenharmony_ci [PERF_RECORD_FORK] = "FORK", 488c2ecf20Sopenharmony_ci [PERF_RECORD_READ] = "READ", 498c2ecf20Sopenharmony_ci [PERF_RECORD_SAMPLE] = "SAMPLE", 508c2ecf20Sopenharmony_ci [PERF_RECORD_AUX] = "AUX", 518c2ecf20Sopenharmony_ci [PERF_RECORD_ITRACE_START] = "ITRACE_START", 528c2ecf20Sopenharmony_ci [PERF_RECORD_LOST_SAMPLES] = "LOST_SAMPLES", 538c2ecf20Sopenharmony_ci [PERF_RECORD_SWITCH] = "SWITCH", 548c2ecf20Sopenharmony_ci [PERF_RECORD_SWITCH_CPU_WIDE] = "SWITCH_CPU_WIDE", 558c2ecf20Sopenharmony_ci [PERF_RECORD_NAMESPACES] = "NAMESPACES", 568c2ecf20Sopenharmony_ci [PERF_RECORD_KSYMBOL] = "KSYMBOL", 578c2ecf20Sopenharmony_ci [PERF_RECORD_BPF_EVENT] = "BPF_EVENT", 588c2ecf20Sopenharmony_ci [PERF_RECORD_CGROUP] = "CGROUP", 598c2ecf20Sopenharmony_ci [PERF_RECORD_TEXT_POKE] = "TEXT_POKE", 608c2ecf20Sopenharmony_ci [PERF_RECORD_HEADER_ATTR] = "ATTR", 618c2ecf20Sopenharmony_ci [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", 628c2ecf20Sopenharmony_ci [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", 638c2ecf20Sopenharmony_ci [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID", 648c2ecf20Sopenharmony_ci [PERF_RECORD_FINISHED_ROUND] = "FINISHED_ROUND", 658c2ecf20Sopenharmony_ci [PERF_RECORD_ID_INDEX] = "ID_INDEX", 668c2ecf20Sopenharmony_ci [PERF_RECORD_AUXTRACE_INFO] = "AUXTRACE_INFO", 678c2ecf20Sopenharmony_ci [PERF_RECORD_AUXTRACE] = "AUXTRACE", 688c2ecf20Sopenharmony_ci [PERF_RECORD_AUXTRACE_ERROR] = "AUXTRACE_ERROR", 698c2ecf20Sopenharmony_ci [PERF_RECORD_THREAD_MAP] = "THREAD_MAP", 708c2ecf20Sopenharmony_ci [PERF_RECORD_CPU_MAP] = "CPU_MAP", 718c2ecf20Sopenharmony_ci [PERF_RECORD_STAT_CONFIG] = "STAT_CONFIG", 728c2ecf20Sopenharmony_ci [PERF_RECORD_STAT] = "STAT", 738c2ecf20Sopenharmony_ci [PERF_RECORD_STAT_ROUND] = "STAT_ROUND", 748c2ecf20Sopenharmony_ci [PERF_RECORD_EVENT_UPDATE] = "EVENT_UPDATE", 758c2ecf20Sopenharmony_ci [PERF_RECORD_TIME_CONV] = "TIME_CONV", 768c2ecf20Sopenharmony_ci [PERF_RECORD_HEADER_FEATURE] = "FEATURE", 778c2ecf20Sopenharmony_ci [PERF_RECORD_COMPRESSED] = "COMPRESSED", 788c2ecf20Sopenharmony_ci}; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ciconst char *perf_event__name(unsigned int id) 818c2ecf20Sopenharmony_ci{ 828c2ecf20Sopenharmony_ci if (id >= ARRAY_SIZE(perf_event__names)) 838c2ecf20Sopenharmony_ci return "INVALID"; 848c2ecf20Sopenharmony_ci if (!perf_event__names[id]) 858c2ecf20Sopenharmony_ci return "UNKNOWN"; 868c2ecf20Sopenharmony_ci return perf_event__names[id]; 878c2ecf20Sopenharmony_ci} 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistruct process_symbol_args { 908c2ecf20Sopenharmony_ci const char *name; 918c2ecf20Sopenharmony_ci u64 start; 928c2ecf20Sopenharmony_ci}; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_cistatic int find_symbol_cb(void *arg, const char *name, char type, 958c2ecf20Sopenharmony_ci u64 start) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci struct process_symbol_args *args = arg; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci /* 1008c2ecf20Sopenharmony_ci * Must be a function or at least an alias, as in PARISC64, where "_text" is 1018c2ecf20Sopenharmony_ci * an 'A' to the same address as "_stext". 1028c2ecf20Sopenharmony_ci */ 1038c2ecf20Sopenharmony_ci if (!(kallsyms__is_function(type) || 1048c2ecf20Sopenharmony_ci type == 'A') || strcmp(name, args->name)) 1058c2ecf20Sopenharmony_ci return 0; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci args->start = start; 1088c2ecf20Sopenharmony_ci return 1; 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ciint kallsyms__get_function_start(const char *kallsyms_filename, 1128c2ecf20Sopenharmony_ci const char *symbol_name, u64 *addr) 1138c2ecf20Sopenharmony_ci{ 1148c2ecf20Sopenharmony_ci struct process_symbol_args args = { .name = symbol_name, }; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci if (kallsyms__parse(kallsyms_filename, &args, find_symbol_cb) <= 0) 1178c2ecf20Sopenharmony_ci return -1; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci *addr = args.start; 1208c2ecf20Sopenharmony_ci return 0; 1218c2ecf20Sopenharmony_ci} 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_civoid perf_event__read_stat_config(struct perf_stat_config *config, 1248c2ecf20Sopenharmony_ci struct perf_record_stat_config *event) 1258c2ecf20Sopenharmony_ci{ 1268c2ecf20Sopenharmony_ci unsigned i; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci for (i = 0; i < event->nr; i++) { 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci switch (event->data[i].tag) { 1318c2ecf20Sopenharmony_ci#define CASE(__term, __val) \ 1328c2ecf20Sopenharmony_ci case PERF_STAT_CONFIG_TERM__##__term: \ 1338c2ecf20Sopenharmony_ci config->__val = event->data[i].val; \ 1348c2ecf20Sopenharmony_ci break; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci CASE(AGGR_MODE, aggr_mode) 1378c2ecf20Sopenharmony_ci CASE(SCALE, scale) 1388c2ecf20Sopenharmony_ci CASE(INTERVAL, interval) 1398c2ecf20Sopenharmony_ci#undef CASE 1408c2ecf20Sopenharmony_ci default: 1418c2ecf20Sopenharmony_ci pr_warning("unknown stat config term %" PRI_lu64 "\n", 1428c2ecf20Sopenharmony_ci event->data[i].tag); 1438c2ecf20Sopenharmony_ci } 1448c2ecf20Sopenharmony_ci } 1458c2ecf20Sopenharmony_ci} 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_cisize_t perf_event__fprintf_comm(union perf_event *event, FILE *fp) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci const char *s; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci if (event->header.misc & PERF_RECORD_MISC_COMM_EXEC) 1528c2ecf20Sopenharmony_ci s = " exec"; 1538c2ecf20Sopenharmony_ci else 1548c2ecf20Sopenharmony_ci s = ""; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci return fprintf(fp, "%s: %s:%d/%d\n", s, event->comm.comm, event->comm.pid, event->comm.tid); 1578c2ecf20Sopenharmony_ci} 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cisize_t perf_event__fprintf_namespaces(union perf_event *event, FILE *fp) 1608c2ecf20Sopenharmony_ci{ 1618c2ecf20Sopenharmony_ci size_t ret = 0; 1628c2ecf20Sopenharmony_ci struct perf_ns_link_info *ns_link_info; 1638c2ecf20Sopenharmony_ci u32 nr_namespaces, idx; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci ns_link_info = event->namespaces.link_info; 1668c2ecf20Sopenharmony_ci nr_namespaces = event->namespaces.nr_namespaces; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci ret += fprintf(fp, " %d/%d - nr_namespaces: %u\n\t\t[", 1698c2ecf20Sopenharmony_ci event->namespaces.pid, 1708c2ecf20Sopenharmony_ci event->namespaces.tid, 1718c2ecf20Sopenharmony_ci nr_namespaces); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci for (idx = 0; idx < nr_namespaces; idx++) { 1748c2ecf20Sopenharmony_ci if (idx && (idx % 4 == 0)) 1758c2ecf20Sopenharmony_ci ret += fprintf(fp, "\n\t\t "); 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci ret += fprintf(fp, "%u/%s: %" PRIu64 "/%#" PRIx64 "%s", idx, 1788c2ecf20Sopenharmony_ci perf_ns__name(idx), (u64)ns_link_info[idx].dev, 1798c2ecf20Sopenharmony_ci (u64)ns_link_info[idx].ino, 1808c2ecf20Sopenharmony_ci ((idx + 1) != nr_namespaces) ? ", " : "]\n"); 1818c2ecf20Sopenharmony_ci } 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci return ret; 1848c2ecf20Sopenharmony_ci} 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_cisize_t perf_event__fprintf_cgroup(union perf_event *event, FILE *fp) 1878c2ecf20Sopenharmony_ci{ 1888c2ecf20Sopenharmony_ci return fprintf(fp, " cgroup: %" PRI_lu64 " %s\n", 1898c2ecf20Sopenharmony_ci event->cgroup.id, event->cgroup.path); 1908c2ecf20Sopenharmony_ci} 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ciint perf_event__process_comm(struct perf_tool *tool __maybe_unused, 1938c2ecf20Sopenharmony_ci union perf_event *event, 1948c2ecf20Sopenharmony_ci struct perf_sample *sample, 1958c2ecf20Sopenharmony_ci struct machine *machine) 1968c2ecf20Sopenharmony_ci{ 1978c2ecf20Sopenharmony_ci return machine__process_comm_event(machine, event, sample); 1988c2ecf20Sopenharmony_ci} 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ciint perf_event__process_namespaces(struct perf_tool *tool __maybe_unused, 2018c2ecf20Sopenharmony_ci union perf_event *event, 2028c2ecf20Sopenharmony_ci struct perf_sample *sample, 2038c2ecf20Sopenharmony_ci struct machine *machine) 2048c2ecf20Sopenharmony_ci{ 2058c2ecf20Sopenharmony_ci return machine__process_namespaces_event(machine, event, sample); 2068c2ecf20Sopenharmony_ci} 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ciint perf_event__process_cgroup(struct perf_tool *tool __maybe_unused, 2098c2ecf20Sopenharmony_ci union perf_event *event, 2108c2ecf20Sopenharmony_ci struct perf_sample *sample, 2118c2ecf20Sopenharmony_ci struct machine *machine) 2128c2ecf20Sopenharmony_ci{ 2138c2ecf20Sopenharmony_ci return machine__process_cgroup_event(machine, event, sample); 2148c2ecf20Sopenharmony_ci} 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ciint perf_event__process_lost(struct perf_tool *tool __maybe_unused, 2178c2ecf20Sopenharmony_ci union perf_event *event, 2188c2ecf20Sopenharmony_ci struct perf_sample *sample, 2198c2ecf20Sopenharmony_ci struct machine *machine) 2208c2ecf20Sopenharmony_ci{ 2218c2ecf20Sopenharmony_ci return machine__process_lost_event(machine, event, sample); 2228c2ecf20Sopenharmony_ci} 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ciint perf_event__process_aux(struct perf_tool *tool __maybe_unused, 2258c2ecf20Sopenharmony_ci union perf_event *event, 2268c2ecf20Sopenharmony_ci struct perf_sample *sample __maybe_unused, 2278c2ecf20Sopenharmony_ci struct machine *machine) 2288c2ecf20Sopenharmony_ci{ 2298c2ecf20Sopenharmony_ci return machine__process_aux_event(machine, event); 2308c2ecf20Sopenharmony_ci} 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ciint perf_event__process_itrace_start(struct perf_tool *tool __maybe_unused, 2338c2ecf20Sopenharmony_ci union perf_event *event, 2348c2ecf20Sopenharmony_ci struct perf_sample *sample __maybe_unused, 2358c2ecf20Sopenharmony_ci struct machine *machine) 2368c2ecf20Sopenharmony_ci{ 2378c2ecf20Sopenharmony_ci return machine__process_itrace_start_event(machine, event); 2388c2ecf20Sopenharmony_ci} 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ciint perf_event__process_lost_samples(struct perf_tool *tool __maybe_unused, 2418c2ecf20Sopenharmony_ci union perf_event *event, 2428c2ecf20Sopenharmony_ci struct perf_sample *sample, 2438c2ecf20Sopenharmony_ci struct machine *machine) 2448c2ecf20Sopenharmony_ci{ 2458c2ecf20Sopenharmony_ci return machine__process_lost_samples_event(machine, event, sample); 2468c2ecf20Sopenharmony_ci} 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ciint perf_event__process_switch(struct perf_tool *tool __maybe_unused, 2498c2ecf20Sopenharmony_ci union perf_event *event, 2508c2ecf20Sopenharmony_ci struct perf_sample *sample __maybe_unused, 2518c2ecf20Sopenharmony_ci struct machine *machine) 2528c2ecf20Sopenharmony_ci{ 2538c2ecf20Sopenharmony_ci return machine__process_switch_event(machine, event); 2548c2ecf20Sopenharmony_ci} 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ciint perf_event__process_ksymbol(struct perf_tool *tool __maybe_unused, 2578c2ecf20Sopenharmony_ci union perf_event *event, 2588c2ecf20Sopenharmony_ci struct perf_sample *sample __maybe_unused, 2598c2ecf20Sopenharmony_ci struct machine *machine) 2608c2ecf20Sopenharmony_ci{ 2618c2ecf20Sopenharmony_ci return machine__process_ksymbol(machine, event, sample); 2628c2ecf20Sopenharmony_ci} 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ciint perf_event__process_bpf(struct perf_tool *tool __maybe_unused, 2658c2ecf20Sopenharmony_ci union perf_event *event, 2668c2ecf20Sopenharmony_ci struct perf_sample *sample, 2678c2ecf20Sopenharmony_ci struct machine *machine) 2688c2ecf20Sopenharmony_ci{ 2698c2ecf20Sopenharmony_ci return machine__process_bpf(machine, event, sample); 2708c2ecf20Sopenharmony_ci} 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ciint perf_event__process_text_poke(struct perf_tool *tool __maybe_unused, 2738c2ecf20Sopenharmony_ci union perf_event *event, 2748c2ecf20Sopenharmony_ci struct perf_sample *sample, 2758c2ecf20Sopenharmony_ci struct machine *machine) 2768c2ecf20Sopenharmony_ci{ 2778c2ecf20Sopenharmony_ci return machine__process_text_poke(machine, event, sample); 2788c2ecf20Sopenharmony_ci} 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_cisize_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) 2818c2ecf20Sopenharmony_ci{ 2828c2ecf20Sopenharmony_ci return fprintf(fp, " %d/%d: [%#" PRI_lx64 "(%#" PRI_lx64 ") @ %#" PRI_lx64 "]: %c %s\n", 2838c2ecf20Sopenharmony_ci event->mmap.pid, event->mmap.tid, event->mmap.start, 2848c2ecf20Sopenharmony_ci event->mmap.len, event->mmap.pgoff, 2858c2ecf20Sopenharmony_ci (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x', 2868c2ecf20Sopenharmony_ci event->mmap.filename); 2878c2ecf20Sopenharmony_ci} 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_cisize_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) 2908c2ecf20Sopenharmony_ci{ 2918c2ecf20Sopenharmony_ci return fprintf(fp, " %d/%d: [%#" PRI_lx64 "(%#" PRI_lx64 ") @ %#" PRI_lx64 2928c2ecf20Sopenharmony_ci " %02x:%02x %"PRI_lu64" %"PRI_lu64"]: %c%c%c%c %s\n", 2938c2ecf20Sopenharmony_ci event->mmap2.pid, event->mmap2.tid, event->mmap2.start, 2948c2ecf20Sopenharmony_ci event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj, 2958c2ecf20Sopenharmony_ci event->mmap2.min, event->mmap2.ino, 2968c2ecf20Sopenharmony_ci event->mmap2.ino_generation, 2978c2ecf20Sopenharmony_ci (event->mmap2.prot & PROT_READ) ? 'r' : '-', 2988c2ecf20Sopenharmony_ci (event->mmap2.prot & PROT_WRITE) ? 'w' : '-', 2998c2ecf20Sopenharmony_ci (event->mmap2.prot & PROT_EXEC) ? 'x' : '-', 3008c2ecf20Sopenharmony_ci (event->mmap2.flags & MAP_SHARED) ? 's' : 'p', 3018c2ecf20Sopenharmony_ci event->mmap2.filename); 3028c2ecf20Sopenharmony_ci} 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_cisize_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp) 3058c2ecf20Sopenharmony_ci{ 3068c2ecf20Sopenharmony_ci struct perf_thread_map *threads = thread_map__new_event(&event->thread_map); 3078c2ecf20Sopenharmony_ci size_t ret; 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci ret = fprintf(fp, " nr: "); 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci if (threads) 3128c2ecf20Sopenharmony_ci ret += thread_map__fprintf(threads, fp); 3138c2ecf20Sopenharmony_ci else 3148c2ecf20Sopenharmony_ci ret += fprintf(fp, "failed to get threads from event\n"); 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci perf_thread_map__put(threads); 3178c2ecf20Sopenharmony_ci return ret; 3188c2ecf20Sopenharmony_ci} 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_cisize_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp) 3218c2ecf20Sopenharmony_ci{ 3228c2ecf20Sopenharmony_ci struct perf_cpu_map *cpus = cpu_map__new_data(&event->cpu_map.data); 3238c2ecf20Sopenharmony_ci size_t ret; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci ret = fprintf(fp, ": "); 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci if (cpus) 3288c2ecf20Sopenharmony_ci ret += cpu_map__fprintf(cpus, fp); 3298c2ecf20Sopenharmony_ci else 3308c2ecf20Sopenharmony_ci ret += fprintf(fp, "failed to get cpumap from event\n"); 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci perf_cpu_map__put(cpus); 3338c2ecf20Sopenharmony_ci return ret; 3348c2ecf20Sopenharmony_ci} 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ciint perf_event__process_mmap(struct perf_tool *tool __maybe_unused, 3378c2ecf20Sopenharmony_ci union perf_event *event, 3388c2ecf20Sopenharmony_ci struct perf_sample *sample, 3398c2ecf20Sopenharmony_ci struct machine *machine) 3408c2ecf20Sopenharmony_ci{ 3418c2ecf20Sopenharmony_ci return machine__process_mmap_event(machine, event, sample); 3428c2ecf20Sopenharmony_ci} 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ciint perf_event__process_mmap2(struct perf_tool *tool __maybe_unused, 3458c2ecf20Sopenharmony_ci union perf_event *event, 3468c2ecf20Sopenharmony_ci struct perf_sample *sample, 3478c2ecf20Sopenharmony_ci struct machine *machine) 3488c2ecf20Sopenharmony_ci{ 3498c2ecf20Sopenharmony_ci return machine__process_mmap2_event(machine, event, sample); 3508c2ecf20Sopenharmony_ci} 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_cisize_t perf_event__fprintf_task(union perf_event *event, FILE *fp) 3538c2ecf20Sopenharmony_ci{ 3548c2ecf20Sopenharmony_ci return fprintf(fp, "(%d:%d):(%d:%d)\n", 3558c2ecf20Sopenharmony_ci event->fork.pid, event->fork.tid, 3568c2ecf20Sopenharmony_ci event->fork.ppid, event->fork.ptid); 3578c2ecf20Sopenharmony_ci} 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ciint perf_event__process_fork(struct perf_tool *tool __maybe_unused, 3608c2ecf20Sopenharmony_ci union perf_event *event, 3618c2ecf20Sopenharmony_ci struct perf_sample *sample, 3628c2ecf20Sopenharmony_ci struct machine *machine) 3638c2ecf20Sopenharmony_ci{ 3648c2ecf20Sopenharmony_ci return machine__process_fork_event(machine, event, sample); 3658c2ecf20Sopenharmony_ci} 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ciint perf_event__process_exit(struct perf_tool *tool __maybe_unused, 3688c2ecf20Sopenharmony_ci union perf_event *event, 3698c2ecf20Sopenharmony_ci struct perf_sample *sample, 3708c2ecf20Sopenharmony_ci struct machine *machine) 3718c2ecf20Sopenharmony_ci{ 3728c2ecf20Sopenharmony_ci return machine__process_exit_event(machine, event, sample); 3738c2ecf20Sopenharmony_ci} 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_cisize_t perf_event__fprintf_aux(union perf_event *event, FILE *fp) 3768c2ecf20Sopenharmony_ci{ 3778c2ecf20Sopenharmony_ci return fprintf(fp, " offset: %#"PRI_lx64" size: %#"PRI_lx64" flags: %#"PRI_lx64" [%s%s%s]\n", 3788c2ecf20Sopenharmony_ci event->aux.aux_offset, event->aux.aux_size, 3798c2ecf20Sopenharmony_ci event->aux.flags, 3808c2ecf20Sopenharmony_ci event->aux.flags & PERF_AUX_FLAG_TRUNCATED ? "T" : "", 3818c2ecf20Sopenharmony_ci event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "", 3828c2ecf20Sopenharmony_ci event->aux.flags & PERF_AUX_FLAG_PARTIAL ? "P" : ""); 3838c2ecf20Sopenharmony_ci} 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_cisize_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp) 3868c2ecf20Sopenharmony_ci{ 3878c2ecf20Sopenharmony_ci return fprintf(fp, " pid: %u tid: %u\n", 3888c2ecf20Sopenharmony_ci event->itrace_start.pid, event->itrace_start.tid); 3898c2ecf20Sopenharmony_ci} 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_cisize_t perf_event__fprintf_switch(union perf_event *event, FILE *fp) 3928c2ecf20Sopenharmony_ci{ 3938c2ecf20Sopenharmony_ci bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT; 3948c2ecf20Sopenharmony_ci const char *in_out = !out ? "IN " : 3958c2ecf20Sopenharmony_ci !(event->header.misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT) ? 3968c2ecf20Sopenharmony_ci "OUT " : "OUT preempt"; 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci if (event->header.type == PERF_RECORD_SWITCH) 3998c2ecf20Sopenharmony_ci return fprintf(fp, " %s\n", in_out); 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci return fprintf(fp, " %s %s pid/tid: %5d/%-5d\n", 4028c2ecf20Sopenharmony_ci in_out, out ? "next" : "prev", 4038c2ecf20Sopenharmony_ci event->context_switch.next_prev_pid, 4048c2ecf20Sopenharmony_ci event->context_switch.next_prev_tid); 4058c2ecf20Sopenharmony_ci} 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_cistatic size_t perf_event__fprintf_lost(union perf_event *event, FILE *fp) 4088c2ecf20Sopenharmony_ci{ 4098c2ecf20Sopenharmony_ci return fprintf(fp, " lost %" PRI_lu64 "\n", event->lost.lost); 4108c2ecf20Sopenharmony_ci} 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_cisize_t perf_event__fprintf_ksymbol(union perf_event *event, FILE *fp) 4138c2ecf20Sopenharmony_ci{ 4148c2ecf20Sopenharmony_ci return fprintf(fp, " addr %" PRI_lx64 " len %u type %u flags 0x%x name %s\n", 4158c2ecf20Sopenharmony_ci event->ksymbol.addr, event->ksymbol.len, 4168c2ecf20Sopenharmony_ci event->ksymbol.ksym_type, 4178c2ecf20Sopenharmony_ci event->ksymbol.flags, event->ksymbol.name); 4188c2ecf20Sopenharmony_ci} 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_cisize_t perf_event__fprintf_bpf(union perf_event *event, FILE *fp) 4218c2ecf20Sopenharmony_ci{ 4228c2ecf20Sopenharmony_ci return fprintf(fp, " type %u, flags %u, id %u\n", 4238c2ecf20Sopenharmony_ci event->bpf.type, event->bpf.flags, event->bpf.id); 4248c2ecf20Sopenharmony_ci} 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_cistatic int text_poke_printer(enum binary_printer_ops op, unsigned int val, 4278c2ecf20Sopenharmony_ci void *extra, FILE *fp) 4288c2ecf20Sopenharmony_ci{ 4298c2ecf20Sopenharmony_ci bool old = *(bool *)extra; 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci switch ((int)op) { 4328c2ecf20Sopenharmony_ci case BINARY_PRINT_LINE_BEGIN: 4338c2ecf20Sopenharmony_ci return fprintf(fp, " %s bytes:", old ? "Old" : "New"); 4348c2ecf20Sopenharmony_ci case BINARY_PRINT_NUM_DATA: 4358c2ecf20Sopenharmony_ci return fprintf(fp, " %02x", val); 4368c2ecf20Sopenharmony_ci case BINARY_PRINT_LINE_END: 4378c2ecf20Sopenharmony_ci return fprintf(fp, "\n"); 4388c2ecf20Sopenharmony_ci default: 4398c2ecf20Sopenharmony_ci return 0; 4408c2ecf20Sopenharmony_ci } 4418c2ecf20Sopenharmony_ci} 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_cisize_t perf_event__fprintf_text_poke(union perf_event *event, struct machine *machine, FILE *fp) 4448c2ecf20Sopenharmony_ci{ 4458c2ecf20Sopenharmony_ci struct perf_record_text_poke_event *tp = &event->text_poke; 4468c2ecf20Sopenharmony_ci size_t ret; 4478c2ecf20Sopenharmony_ci bool old; 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_ci ret = fprintf(fp, " %" PRI_lx64 " ", tp->addr); 4508c2ecf20Sopenharmony_ci if (machine) { 4518c2ecf20Sopenharmony_ci struct addr_location al; 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci al.map = maps__find(&machine->kmaps, tp->addr); 4548c2ecf20Sopenharmony_ci if (al.map && map__load(al.map) >= 0) { 4558c2ecf20Sopenharmony_ci al.addr = al.map->map_ip(al.map, tp->addr); 4568c2ecf20Sopenharmony_ci al.sym = map__find_symbol(al.map, al.addr); 4578c2ecf20Sopenharmony_ci if (al.sym) 4588c2ecf20Sopenharmony_ci ret += symbol__fprintf_symname_offs(al.sym, &al, fp); 4598c2ecf20Sopenharmony_ci } 4608c2ecf20Sopenharmony_ci } 4618c2ecf20Sopenharmony_ci ret += fprintf(fp, " old len %u new len %u\n", tp->old_len, tp->new_len); 4628c2ecf20Sopenharmony_ci old = true; 4638c2ecf20Sopenharmony_ci ret += binary__fprintf(tp->bytes, tp->old_len, 16, text_poke_printer, 4648c2ecf20Sopenharmony_ci &old, fp); 4658c2ecf20Sopenharmony_ci old = false; 4668c2ecf20Sopenharmony_ci ret += binary__fprintf(tp->bytes + tp->old_len, tp->new_len, 16, 4678c2ecf20Sopenharmony_ci text_poke_printer, &old, fp); 4688c2ecf20Sopenharmony_ci return ret; 4698c2ecf20Sopenharmony_ci} 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_cisize_t perf_event__fprintf(union perf_event *event, struct machine *machine, FILE *fp) 4728c2ecf20Sopenharmony_ci{ 4738c2ecf20Sopenharmony_ci size_t ret = fprintf(fp, "PERF_RECORD_%s", 4748c2ecf20Sopenharmony_ci perf_event__name(event->header.type)); 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci switch (event->header.type) { 4778c2ecf20Sopenharmony_ci case PERF_RECORD_COMM: 4788c2ecf20Sopenharmony_ci ret += perf_event__fprintf_comm(event, fp); 4798c2ecf20Sopenharmony_ci break; 4808c2ecf20Sopenharmony_ci case PERF_RECORD_FORK: 4818c2ecf20Sopenharmony_ci case PERF_RECORD_EXIT: 4828c2ecf20Sopenharmony_ci ret += perf_event__fprintf_task(event, fp); 4838c2ecf20Sopenharmony_ci break; 4848c2ecf20Sopenharmony_ci case PERF_RECORD_MMAP: 4858c2ecf20Sopenharmony_ci ret += perf_event__fprintf_mmap(event, fp); 4868c2ecf20Sopenharmony_ci break; 4878c2ecf20Sopenharmony_ci case PERF_RECORD_NAMESPACES: 4888c2ecf20Sopenharmony_ci ret += perf_event__fprintf_namespaces(event, fp); 4898c2ecf20Sopenharmony_ci break; 4908c2ecf20Sopenharmony_ci case PERF_RECORD_CGROUP: 4918c2ecf20Sopenharmony_ci ret += perf_event__fprintf_cgroup(event, fp); 4928c2ecf20Sopenharmony_ci break; 4938c2ecf20Sopenharmony_ci case PERF_RECORD_MMAP2: 4948c2ecf20Sopenharmony_ci ret += perf_event__fprintf_mmap2(event, fp); 4958c2ecf20Sopenharmony_ci break; 4968c2ecf20Sopenharmony_ci case PERF_RECORD_AUX: 4978c2ecf20Sopenharmony_ci ret += perf_event__fprintf_aux(event, fp); 4988c2ecf20Sopenharmony_ci break; 4998c2ecf20Sopenharmony_ci case PERF_RECORD_ITRACE_START: 5008c2ecf20Sopenharmony_ci ret += perf_event__fprintf_itrace_start(event, fp); 5018c2ecf20Sopenharmony_ci break; 5028c2ecf20Sopenharmony_ci case PERF_RECORD_SWITCH: 5038c2ecf20Sopenharmony_ci case PERF_RECORD_SWITCH_CPU_WIDE: 5048c2ecf20Sopenharmony_ci ret += perf_event__fprintf_switch(event, fp); 5058c2ecf20Sopenharmony_ci break; 5068c2ecf20Sopenharmony_ci case PERF_RECORD_LOST: 5078c2ecf20Sopenharmony_ci ret += perf_event__fprintf_lost(event, fp); 5088c2ecf20Sopenharmony_ci break; 5098c2ecf20Sopenharmony_ci case PERF_RECORD_KSYMBOL: 5108c2ecf20Sopenharmony_ci ret += perf_event__fprintf_ksymbol(event, fp); 5118c2ecf20Sopenharmony_ci break; 5128c2ecf20Sopenharmony_ci case PERF_RECORD_BPF_EVENT: 5138c2ecf20Sopenharmony_ci ret += perf_event__fprintf_bpf(event, fp); 5148c2ecf20Sopenharmony_ci break; 5158c2ecf20Sopenharmony_ci case PERF_RECORD_TEXT_POKE: 5168c2ecf20Sopenharmony_ci ret += perf_event__fprintf_text_poke(event, machine, fp); 5178c2ecf20Sopenharmony_ci break; 5188c2ecf20Sopenharmony_ci default: 5198c2ecf20Sopenharmony_ci ret += fprintf(fp, "\n"); 5208c2ecf20Sopenharmony_ci } 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_ci return ret; 5238c2ecf20Sopenharmony_ci} 5248c2ecf20Sopenharmony_ci 5258c2ecf20Sopenharmony_ciint perf_event__process(struct perf_tool *tool __maybe_unused, 5268c2ecf20Sopenharmony_ci union perf_event *event, 5278c2ecf20Sopenharmony_ci struct perf_sample *sample, 5288c2ecf20Sopenharmony_ci struct machine *machine) 5298c2ecf20Sopenharmony_ci{ 5308c2ecf20Sopenharmony_ci return machine__process_event(machine, event, sample); 5318c2ecf20Sopenharmony_ci} 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_cistruct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, 5348c2ecf20Sopenharmony_ci struct addr_location *al) 5358c2ecf20Sopenharmony_ci{ 5368c2ecf20Sopenharmony_ci struct maps *maps = thread->maps; 5378c2ecf20Sopenharmony_ci struct machine *machine = maps->machine; 5388c2ecf20Sopenharmony_ci bool load_map = false; 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci al->maps = maps; 5418c2ecf20Sopenharmony_ci al->thread = thread; 5428c2ecf20Sopenharmony_ci al->addr = addr; 5438c2ecf20Sopenharmony_ci al->cpumode = cpumode; 5448c2ecf20Sopenharmony_ci al->filtered = 0; 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_ci if (machine == NULL) { 5478c2ecf20Sopenharmony_ci al->map = NULL; 5488c2ecf20Sopenharmony_ci return NULL; 5498c2ecf20Sopenharmony_ci } 5508c2ecf20Sopenharmony_ci 5518c2ecf20Sopenharmony_ci if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { 5528c2ecf20Sopenharmony_ci al->level = 'k'; 5538c2ecf20Sopenharmony_ci al->maps = maps = &machine->kmaps; 5548c2ecf20Sopenharmony_ci load_map = true; 5558c2ecf20Sopenharmony_ci } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { 5568c2ecf20Sopenharmony_ci al->level = '.'; 5578c2ecf20Sopenharmony_ci } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { 5588c2ecf20Sopenharmony_ci al->level = 'g'; 5598c2ecf20Sopenharmony_ci al->maps = maps = &machine->kmaps; 5608c2ecf20Sopenharmony_ci load_map = true; 5618c2ecf20Sopenharmony_ci } else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) { 5628c2ecf20Sopenharmony_ci al->level = 'u'; 5638c2ecf20Sopenharmony_ci } else { 5648c2ecf20Sopenharmony_ci al->level = 'H'; 5658c2ecf20Sopenharmony_ci al->map = NULL; 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_ci if ((cpumode == PERF_RECORD_MISC_GUEST_USER || 5688c2ecf20Sopenharmony_ci cpumode == PERF_RECORD_MISC_GUEST_KERNEL) && 5698c2ecf20Sopenharmony_ci !perf_guest) 5708c2ecf20Sopenharmony_ci al->filtered |= (1 << HIST_FILTER__GUEST); 5718c2ecf20Sopenharmony_ci if ((cpumode == PERF_RECORD_MISC_USER || 5728c2ecf20Sopenharmony_ci cpumode == PERF_RECORD_MISC_KERNEL) && 5738c2ecf20Sopenharmony_ci !perf_host) 5748c2ecf20Sopenharmony_ci al->filtered |= (1 << HIST_FILTER__HOST); 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_ci return NULL; 5778c2ecf20Sopenharmony_ci } 5788c2ecf20Sopenharmony_ci 5798c2ecf20Sopenharmony_ci al->map = maps__find(maps, al->addr); 5808c2ecf20Sopenharmony_ci if (al->map != NULL) { 5818c2ecf20Sopenharmony_ci /* 5828c2ecf20Sopenharmony_ci * Kernel maps might be changed when loading symbols so loading 5838c2ecf20Sopenharmony_ci * must be done prior to using kernel maps. 5848c2ecf20Sopenharmony_ci */ 5858c2ecf20Sopenharmony_ci if (load_map) 5868c2ecf20Sopenharmony_ci map__load(al->map); 5878c2ecf20Sopenharmony_ci al->addr = al->map->map_ip(al->map, al->addr); 5888c2ecf20Sopenharmony_ci } 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ci return al->map; 5918c2ecf20Sopenharmony_ci} 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci/* 5948c2ecf20Sopenharmony_ci * For branch stacks or branch samples, the sample cpumode might not be correct 5958c2ecf20Sopenharmony_ci * because it applies only to the sample 'ip' and not necessary to 'addr' or 5968c2ecf20Sopenharmony_ci * branch stack addresses. If possible, use a fallback to deal with those cases. 5978c2ecf20Sopenharmony_ci */ 5988c2ecf20Sopenharmony_cistruct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr, 5998c2ecf20Sopenharmony_ci struct addr_location *al) 6008c2ecf20Sopenharmony_ci{ 6018c2ecf20Sopenharmony_ci struct map *map = thread__find_map(thread, cpumode, addr, al); 6028c2ecf20Sopenharmony_ci struct machine *machine = thread->maps->machine; 6038c2ecf20Sopenharmony_ci u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr); 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci if (map || addr_cpumode == cpumode) 6068c2ecf20Sopenharmony_ci return map; 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_ci return thread__find_map(thread, addr_cpumode, addr, al); 6098c2ecf20Sopenharmony_ci} 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_cistruct symbol *thread__find_symbol(struct thread *thread, u8 cpumode, 6128c2ecf20Sopenharmony_ci u64 addr, struct addr_location *al) 6138c2ecf20Sopenharmony_ci{ 6148c2ecf20Sopenharmony_ci al->sym = NULL; 6158c2ecf20Sopenharmony_ci if (thread__find_map(thread, cpumode, addr, al)) 6168c2ecf20Sopenharmony_ci al->sym = map__find_symbol(al->map, al->addr); 6178c2ecf20Sopenharmony_ci return al->sym; 6188c2ecf20Sopenharmony_ci} 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_cistruct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode, 6218c2ecf20Sopenharmony_ci u64 addr, struct addr_location *al) 6228c2ecf20Sopenharmony_ci{ 6238c2ecf20Sopenharmony_ci al->sym = NULL; 6248c2ecf20Sopenharmony_ci if (thread__find_map_fb(thread, cpumode, addr, al)) 6258c2ecf20Sopenharmony_ci al->sym = map__find_symbol(al->map, al->addr); 6268c2ecf20Sopenharmony_ci return al->sym; 6278c2ecf20Sopenharmony_ci} 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci/* 6308c2ecf20Sopenharmony_ci * Callers need to drop the reference to al->thread, obtained in 6318c2ecf20Sopenharmony_ci * machine__findnew_thread() 6328c2ecf20Sopenharmony_ci */ 6338c2ecf20Sopenharmony_ciint machine__resolve(struct machine *machine, struct addr_location *al, 6348c2ecf20Sopenharmony_ci struct perf_sample *sample) 6358c2ecf20Sopenharmony_ci{ 6368c2ecf20Sopenharmony_ci struct thread *thread = machine__findnew_thread(machine, sample->pid, 6378c2ecf20Sopenharmony_ci sample->tid); 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci if (thread == NULL) 6408c2ecf20Sopenharmony_ci return -1; 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_ci dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid); 6438c2ecf20Sopenharmony_ci thread__find_map(thread, sample->cpumode, sample->ip, al); 6448c2ecf20Sopenharmony_ci dump_printf(" ...... dso: %s\n", 6458c2ecf20Sopenharmony_ci al->map ? al->map->dso->long_name : 6468c2ecf20Sopenharmony_ci al->level == 'H' ? "[hypervisor]" : "<not found>"); 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci if (thread__is_filtered(thread)) 6498c2ecf20Sopenharmony_ci al->filtered |= (1 << HIST_FILTER__THREAD); 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_ci al->sym = NULL; 6528c2ecf20Sopenharmony_ci al->cpu = sample->cpu; 6538c2ecf20Sopenharmony_ci al->socket = -1; 6548c2ecf20Sopenharmony_ci al->srcline = NULL; 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci if (al->cpu >= 0) { 6578c2ecf20Sopenharmony_ci struct perf_env *env = machine->env; 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_ci if (env && env->cpu) 6608c2ecf20Sopenharmony_ci al->socket = env->cpu[al->cpu].socket_id; 6618c2ecf20Sopenharmony_ci } 6628c2ecf20Sopenharmony_ci 6638c2ecf20Sopenharmony_ci if (al->map) { 6648c2ecf20Sopenharmony_ci struct dso *dso = al->map->dso; 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci if (symbol_conf.dso_list && 6678c2ecf20Sopenharmony_ci (!dso || !(strlist__has_entry(symbol_conf.dso_list, 6688c2ecf20Sopenharmony_ci dso->short_name) || 6698c2ecf20Sopenharmony_ci (dso->short_name != dso->long_name && 6708c2ecf20Sopenharmony_ci strlist__has_entry(symbol_conf.dso_list, 6718c2ecf20Sopenharmony_ci dso->long_name))))) { 6728c2ecf20Sopenharmony_ci al->filtered |= (1 << HIST_FILTER__DSO); 6738c2ecf20Sopenharmony_ci } 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_ci al->sym = map__find_symbol(al->map, al->addr); 6768c2ecf20Sopenharmony_ci } else if (symbol_conf.dso_list) { 6778c2ecf20Sopenharmony_ci al->filtered |= (1 << HIST_FILTER__DSO); 6788c2ecf20Sopenharmony_ci } 6798c2ecf20Sopenharmony_ci 6808c2ecf20Sopenharmony_ci if (symbol_conf.sym_list) { 6818c2ecf20Sopenharmony_ci int ret = 0; 6828c2ecf20Sopenharmony_ci char al_addr_str[32]; 6838c2ecf20Sopenharmony_ci size_t sz = sizeof(al_addr_str); 6848c2ecf20Sopenharmony_ci 6858c2ecf20Sopenharmony_ci if (al->sym) { 6868c2ecf20Sopenharmony_ci ret = strlist__has_entry(symbol_conf.sym_list, 6878c2ecf20Sopenharmony_ci al->sym->name); 6888c2ecf20Sopenharmony_ci } 6898c2ecf20Sopenharmony_ci if (!ret && al->sym) { 6908c2ecf20Sopenharmony_ci snprintf(al_addr_str, sz, "0x%"PRIx64, 6918c2ecf20Sopenharmony_ci al->map->unmap_ip(al->map, al->sym->start)); 6928c2ecf20Sopenharmony_ci ret = strlist__has_entry(symbol_conf.sym_list, 6938c2ecf20Sopenharmony_ci al_addr_str); 6948c2ecf20Sopenharmony_ci } 6958c2ecf20Sopenharmony_ci if (!ret) 6968c2ecf20Sopenharmony_ci al->filtered |= (1 << HIST_FILTER__SYMBOL); 6978c2ecf20Sopenharmony_ci } 6988c2ecf20Sopenharmony_ci 6998c2ecf20Sopenharmony_ci return 0; 7008c2ecf20Sopenharmony_ci} 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_ci/* 7038c2ecf20Sopenharmony_ci * The preprocess_sample method will return with reference counts for the 7048c2ecf20Sopenharmony_ci * in it, when done using (and perhaps getting ref counts if needing to 7058c2ecf20Sopenharmony_ci * keep a pointer to one of those entries) it must be paired with 7068c2ecf20Sopenharmony_ci * addr_location__put(), so that the refcounts can be decremented. 7078c2ecf20Sopenharmony_ci */ 7088c2ecf20Sopenharmony_civoid addr_location__put(struct addr_location *al) 7098c2ecf20Sopenharmony_ci{ 7108c2ecf20Sopenharmony_ci thread__zput(al->thread); 7118c2ecf20Sopenharmony_ci} 7128c2ecf20Sopenharmony_ci 7138c2ecf20Sopenharmony_cibool is_bts_event(struct perf_event_attr *attr) 7148c2ecf20Sopenharmony_ci{ 7158c2ecf20Sopenharmony_ci return attr->type == PERF_TYPE_HARDWARE && 7168c2ecf20Sopenharmony_ci (attr->config & PERF_COUNT_HW_BRANCH_INSTRUCTIONS) && 7178c2ecf20Sopenharmony_ci attr->sample_period == 1; 7188c2ecf20Sopenharmony_ci} 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_cibool sample_addr_correlates_sym(struct perf_event_attr *attr) 7218c2ecf20Sopenharmony_ci{ 7228c2ecf20Sopenharmony_ci if (attr->type == PERF_TYPE_SOFTWARE && 7238c2ecf20Sopenharmony_ci (attr->config == PERF_COUNT_SW_PAGE_FAULTS || 7248c2ecf20Sopenharmony_ci attr->config == PERF_COUNT_SW_PAGE_FAULTS_MIN || 7258c2ecf20Sopenharmony_ci attr->config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)) 7268c2ecf20Sopenharmony_ci return true; 7278c2ecf20Sopenharmony_ci 7288c2ecf20Sopenharmony_ci if (is_bts_event(attr)) 7298c2ecf20Sopenharmony_ci return true; 7308c2ecf20Sopenharmony_ci 7318c2ecf20Sopenharmony_ci return false; 7328c2ecf20Sopenharmony_ci} 7338c2ecf20Sopenharmony_ci 7348c2ecf20Sopenharmony_civoid thread__resolve(struct thread *thread, struct addr_location *al, 7358c2ecf20Sopenharmony_ci struct perf_sample *sample) 7368c2ecf20Sopenharmony_ci{ 7378c2ecf20Sopenharmony_ci thread__find_map_fb(thread, sample->cpumode, sample->addr, al); 7388c2ecf20Sopenharmony_ci 7398c2ecf20Sopenharmony_ci al->cpu = sample->cpu; 7408c2ecf20Sopenharmony_ci al->sym = NULL; 7418c2ecf20Sopenharmony_ci 7428c2ecf20Sopenharmony_ci if (al->map) 7438c2ecf20Sopenharmony_ci al->sym = map__find_symbol(al->map, al->addr); 7448c2ecf20Sopenharmony_ci} 745