19b7c7728SIan Rogers // SPDX-License-Identifier: GPL-2.0
29b7c7728SIan Rogers #include <dirent.h>
39b7c7728SIan Rogers #include <errno.h>
49b7c7728SIan Rogers #include <stdio.h>
59b7c7728SIan Rogers #include <stdlib.h>
69b7c7728SIan Rogers #include <string.h>
700462d8eSNamhyung Kim #include <fcntl.h>
89b7c7728SIan Rogers #include <sys/param.h>
900462d8eSNamhyung Kim #include <unistd.h>
109b7c7728SIan Rogers
119b7c7728SIan Rogers #include <api/fs/tracing_path.h>
129b7c7728SIan Rogers #include <linux/stddef.h>
139b7c7728SIan Rogers #include <linux/perf_event.h>
149b7c7728SIan Rogers #include <linux/zalloc.h>
159b7c7728SIan Rogers #include <subcmd/pager.h>
169b7c7728SIan Rogers
179b7c7728SIan Rogers #include "build-id.h"
189b7c7728SIan Rogers #include "debug.h"
199b7c7728SIan Rogers #include "evsel.h"
209b7c7728SIan Rogers #include "metricgroup.h"
219b7c7728SIan Rogers #include "parse-events.h"
229b7c7728SIan Rogers #include "pmu.h"
231eaf496eSIan Rogers #include "pmus.h"
249b7c7728SIan Rogers #include "print-events.h"
259b7c7728SIan Rogers #include "probe-file.h"
269b7c7728SIan Rogers #include "string2.h"
279b7c7728SIan Rogers #include "strlist.h"
289b7c7728SIan Rogers #include "tracepoint.h"
299b7c7728SIan Rogers #include "pfm.h"
309a1bc9eaSIan Rogers #include "thread_map.h"
319b7c7728SIan Rogers
329b7c7728SIan Rogers #define MAX_NAME_LEN 100
339b7c7728SIan Rogers
34e5c6109fSIan Rogers /** Strings corresponding to enum perf_type_id. */
359b7c7728SIan Rogers static const char * const event_type_descriptors[] = {
369b7c7728SIan Rogers "Hardware event",
379b7c7728SIan Rogers "Software event",
389b7c7728SIan Rogers "Tracepoint event",
399b7c7728SIan Rogers "Hardware cache event",
409b7c7728SIan Rogers "Raw hardware event descriptor",
419b7c7728SIan Rogers "Hardware breakpoint",
429b7c7728SIan Rogers };
439b7c7728SIan Rogers
449b7c7728SIan Rogers static const struct event_symbol event_symbols_tool[PERF_TOOL_MAX] = {
459b7c7728SIan Rogers [PERF_TOOL_DURATION_TIME] = {
469b7c7728SIan Rogers .symbol = "duration_time",
479b7c7728SIan Rogers .alias = "",
489b7c7728SIan Rogers },
499b7c7728SIan Rogers [PERF_TOOL_USER_TIME] = {
509b7c7728SIan Rogers .symbol = "user_time",
519b7c7728SIan Rogers .alias = "",
529b7c7728SIan Rogers },
539b7c7728SIan Rogers [PERF_TOOL_SYSTEM_TIME] = {
549b7c7728SIan Rogers .symbol = "system_time",
559b7c7728SIan Rogers .alias = "",
569b7c7728SIan Rogers },
579b7c7728SIan Rogers };
589b7c7728SIan Rogers
599b7c7728SIan Rogers /*
609b7c7728SIan Rogers * Print the events from <debugfs_mount_point>/tracing/events
619b7c7728SIan Rogers */
print_tracepoint_events(const struct print_callbacks * print_cb __maybe_unused,void * print_state __maybe_unused)6200462d8eSNamhyung Kim void print_tracepoint_events(const struct print_callbacks *print_cb __maybe_unused, void *print_state __maybe_unused)
6300462d8eSNamhyung Kim {
6400462d8eSNamhyung Kim char *events_path = get_tracing_file("events");
6500462d8eSNamhyung Kim int events_fd = open(events_path, O_PATH);
6600462d8eSNamhyung Kim
6700462d8eSNamhyung Kim put_tracing_file(events_path);
6800462d8eSNamhyung Kim if (events_fd < 0) {
6900462d8eSNamhyung Kim printf("Error: failed to open tracing events directory\n");
7000462d8eSNamhyung Kim return;
7100462d8eSNamhyung Kim }
7200462d8eSNamhyung Kim
7300462d8eSNamhyung Kim #ifdef HAVE_SCANDIRAT_SUPPORT
749b7c7728SIan Rogers {
75d74060c0SIan Rogers struct dirent **sys_namelist = NULL;
76d74060c0SIan Rogers int sys_items = tracing_events__scandir_alphasort(&sys_namelist);
77d74060c0SIan Rogers
78d74060c0SIan Rogers for (int i = 0; i < sys_items; i++) {
79d74060c0SIan Rogers struct dirent *sys_dirent = sys_namelist[i];
80d74060c0SIan Rogers struct dirent **evt_namelist = NULL;
8100462d8eSNamhyung Kim int dir_fd;
82d74060c0SIan Rogers int evt_items;
839b7c7728SIan Rogers
84d74060c0SIan Rogers if (sys_dirent->d_type != DT_DIR ||
85d74060c0SIan Rogers !strcmp(sys_dirent->d_name, ".") ||
86d74060c0SIan Rogers !strcmp(sys_dirent->d_name, ".."))
877586d11dSNamhyung Kim goto next_sys;
889b7c7728SIan Rogers
8900462d8eSNamhyung Kim dir_fd = openat(events_fd, sys_dirent->d_name, O_PATH);
9000462d8eSNamhyung Kim if (dir_fd < 0)
917586d11dSNamhyung Kim goto next_sys;
929b7c7728SIan Rogers
9300462d8eSNamhyung Kim evt_items = scandirat(events_fd, sys_dirent->d_name, &evt_namelist, NULL, alphasort);
94d74060c0SIan Rogers for (int j = 0; j < evt_items; j++) {
95d74060c0SIan Rogers struct dirent *evt_dirent = evt_namelist[j];
96d74060c0SIan Rogers char evt_path[MAXPATHLEN];
9700462d8eSNamhyung Kim int evt_fd;
98d74060c0SIan Rogers
99d74060c0SIan Rogers if (evt_dirent->d_type != DT_DIR ||
100d74060c0SIan Rogers !strcmp(evt_dirent->d_name, ".") ||
101d74060c0SIan Rogers !strcmp(evt_dirent->d_name, ".."))
1027586d11dSNamhyung Kim goto next_evt;
103d74060c0SIan Rogers
10400462d8eSNamhyung Kim snprintf(evt_path, sizeof(evt_path), "%s/id", evt_dirent->d_name);
10500462d8eSNamhyung Kim evt_fd = openat(dir_fd, evt_path, O_RDONLY);
10600462d8eSNamhyung Kim if (evt_fd < 0)
1077586d11dSNamhyung Kim goto next_evt;
10800462d8eSNamhyung Kim close(evt_fd);
109d74060c0SIan Rogers
1109b7c7728SIan Rogers snprintf(evt_path, MAXPATHLEN, "%s:%s",
1119b7c7728SIan Rogers sys_dirent->d_name, evt_dirent->d_name);
112e5c6109fSIan Rogers print_cb->print_event(print_state,
113e5c6109fSIan Rogers /*topic=*/NULL,
114e5c6109fSIan Rogers /*pmu_name=*/NULL,
115e5c6109fSIan Rogers evt_path,
116e5c6109fSIan Rogers /*event_alias=*/NULL,
117e5c6109fSIan Rogers /*scale_unit=*/NULL,
118e5c6109fSIan Rogers /*deprecated=*/false,
119e5c6109fSIan Rogers "Tracepoint event",
120e5c6109fSIan Rogers /*desc=*/NULL,
121e5c6109fSIan Rogers /*long_desc=*/NULL,
122d9dc8874SIan Rogers /*encoding_desc=*/NULL);
1237586d11dSNamhyung Kim next_evt:
1247586d11dSNamhyung Kim free(evt_namelist[j]);
125d74060c0SIan Rogers }
12600462d8eSNamhyung Kim close(dir_fd);
127d74060c0SIan Rogers free(evt_namelist);
1287586d11dSNamhyung Kim next_sys:
1297586d11dSNamhyung Kim free(sys_namelist[i]);
130d74060c0SIan Rogers }
13100462d8eSNamhyung Kim
132d74060c0SIan Rogers free(sys_namelist);
1339b7c7728SIan Rogers }
13400462d8eSNamhyung Kim #else
1356a7b57d8SNamhyung Kim printf("\nWARNING: Your libc doesn't have the scandirat function, please ask its maintainers to implement it.\n"
13600462d8eSNamhyung Kim " As a rough fallback, please do 'ls %s' to see the available tracepoint events.\n", events_path);
13700462d8eSNamhyung Kim #endif
13800462d8eSNamhyung Kim close(events_fd);
13900462d8eSNamhyung Kim }
1409b7c7728SIan Rogers
print_sdt_events(const struct print_callbacks * print_cb,void * print_state)141e5c6109fSIan Rogers void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)
1429b7c7728SIan Rogers {
1439b7c7728SIan Rogers struct strlist *bidlist, *sdtlist;
144e5c6109fSIan Rogers struct str_node *bid_nd, *sdt_name, *next_sdt_name;
145e5c6109fSIan Rogers const char *last_sdt_name = NULL;
1469b7c7728SIan Rogers
147e5c6109fSIan Rogers /*
148e5c6109fSIan Rogers * The implicitly sorted sdtlist will hold the tracepoint name followed
149e5c6109fSIan Rogers * by @<buildid>. If the tracepoint name is unique (determined by
150e5c6109fSIan Rogers * looking at the adjacent nodes) the @<buildid> is dropped otherwise
151e5c6109fSIan Rogers * the executable path and buildid are added to the name.
152e5c6109fSIan Rogers */
153e5c6109fSIan Rogers sdtlist = strlist__new(NULL, NULL);
1549b7c7728SIan Rogers if (!sdtlist) {
1559b7c7728SIan Rogers pr_debug("Failed to allocate new strlist for SDT\n");
1569b7c7728SIan Rogers return;
1579b7c7728SIan Rogers }
1589b7c7728SIan Rogers bidlist = build_id_cache__list_all(true);
1599b7c7728SIan Rogers if (!bidlist) {
1609b7c7728SIan Rogers pr_debug("Failed to get buildids: %d\n", errno);
1619b7c7728SIan Rogers return;
1629b7c7728SIan Rogers }
163e5c6109fSIan Rogers strlist__for_each_entry(bid_nd, bidlist) {
164e5c6109fSIan Rogers struct probe_cache *pcache;
165e5c6109fSIan Rogers struct probe_cache_entry *ent;
166e5c6109fSIan Rogers
167e5c6109fSIan Rogers pcache = probe_cache__new(bid_nd->s, NULL);
1689b7c7728SIan Rogers if (!pcache)
1699b7c7728SIan Rogers continue;
1709b7c7728SIan Rogers list_for_each_entry(ent, &pcache->entries, node) {
171e5c6109fSIan Rogers char buf[1024];
172e5c6109fSIan Rogers
173e5c6109fSIan Rogers snprintf(buf, sizeof(buf), "%s:%s@%s",
174e5c6109fSIan Rogers ent->pev.group, ent->pev.event, bid_nd->s);
1759b7c7728SIan Rogers strlist__add(sdtlist, buf);
1769b7c7728SIan Rogers }
1779b7c7728SIan Rogers probe_cache__delete(pcache);
1789b7c7728SIan Rogers }
1799b7c7728SIan Rogers strlist__delete(bidlist);
1809b7c7728SIan Rogers
181e5c6109fSIan Rogers strlist__for_each_entry(sdt_name, sdtlist) {
182e5c6109fSIan Rogers bool show_detail = false;
183e5c6109fSIan Rogers char *bid = strchr(sdt_name->s, '@');
184e5c6109fSIan Rogers char *evt_name = NULL;
185e5c6109fSIan Rogers
186e5c6109fSIan Rogers if (bid)
187e5c6109fSIan Rogers *(bid++) = '\0';
188e5c6109fSIan Rogers
189e5c6109fSIan Rogers if (last_sdt_name && !strcmp(last_sdt_name, sdt_name->s)) {
1909b7c7728SIan Rogers show_detail = true;
191e5c6109fSIan Rogers } else {
192e5c6109fSIan Rogers next_sdt_name = strlist__next(sdt_name);
193e5c6109fSIan Rogers if (next_sdt_name) {
194e5c6109fSIan Rogers char *bid2 = strchr(next_sdt_name->s, '@');
195e5c6109fSIan Rogers
196e5c6109fSIan Rogers if (bid2)
197e5c6109fSIan Rogers *bid2 = '\0';
198e5c6109fSIan Rogers if (strcmp(sdt_name->s, next_sdt_name->s) == 0)
199e5c6109fSIan Rogers show_detail = true;
200e5c6109fSIan Rogers if (bid2)
201e5c6109fSIan Rogers *bid2 = '@';
2029b7c7728SIan Rogers }
203e5c6109fSIan Rogers }
204e5c6109fSIan Rogers last_sdt_name = sdt_name->s;
205e5c6109fSIan Rogers
2069b7c7728SIan Rogers if (show_detail) {
207e5c6109fSIan Rogers char *path = build_id_cache__origname(bid);
208e5c6109fSIan Rogers
209e5c6109fSIan Rogers if (path) {
210e5c6109fSIan Rogers if (asprintf(&evt_name, "%s@%s(%.12s)", sdt_name->s, path, bid) < 0)
211e5c6109fSIan Rogers evt_name = NULL;
2129b7c7728SIan Rogers free(path);
2139b7c7728SIan Rogers }
2149b7c7728SIan Rogers }
215e5c6109fSIan Rogers print_cb->print_event(print_state,
216e5c6109fSIan Rogers /*topic=*/NULL,
217e5c6109fSIan Rogers /*pmu_name=*/NULL,
218e5c6109fSIan Rogers evt_name ?: sdt_name->s,
219e5c6109fSIan Rogers /*event_alias=*/NULL,
220e5c6109fSIan Rogers /*deprecated=*/false,
221e5c6109fSIan Rogers /*scale_unit=*/NULL,
222e5c6109fSIan Rogers "SDT event",
223e5c6109fSIan Rogers /*desc=*/NULL,
224e5c6109fSIan Rogers /*long_desc=*/NULL,
225d9dc8874SIan Rogers /*encoding_desc=*/NULL);
226e5c6109fSIan Rogers
227e5c6109fSIan Rogers free(evt_name);
228e5c6109fSIan Rogers }
2299b7c7728SIan Rogers strlist__delete(sdtlist);
2309b7c7728SIan Rogers }
2319b7c7728SIan Rogers
is_event_supported(u8 type,u64 config)232e2be0666SArnaldo Carvalho de Melo bool is_event_supported(u8 type, u64 config)
2339a1bc9eaSIan Rogers {
2349a1bc9eaSIan Rogers bool ret = true;
2359a1bc9eaSIan Rogers struct evsel *evsel;
2369a1bc9eaSIan Rogers struct perf_event_attr attr = {
2379a1bc9eaSIan Rogers .type = type,
2389a1bc9eaSIan Rogers .config = config,
2399a1bc9eaSIan Rogers .disabled = 1,
2409a1bc9eaSIan Rogers };
2419a1bc9eaSIan Rogers struct perf_thread_map *tmap = thread_map__new_by_tid(0);
2429a1bc9eaSIan Rogers
2439a1bc9eaSIan Rogers if (tmap == NULL)
2449a1bc9eaSIan Rogers return false;
2459a1bc9eaSIan Rogers
2469a1bc9eaSIan Rogers evsel = evsel__new(&attr);
2479a1bc9eaSIan Rogers if (evsel) {
248*f88698d6SMark Rutland ret = evsel__open(evsel, NULL, tmap) >= 0;
2499a1bc9eaSIan Rogers
250*f88698d6SMark Rutland if (!ret) {
2519a1bc9eaSIan Rogers /*
252*f88698d6SMark Rutland * The event may fail to open if the paranoid value
2539a1bc9eaSIan Rogers * /proc/sys/kernel/perf_event_paranoid is set to 2
254*f88698d6SMark Rutland * Re-run with exclude_kernel set; we don't do that by
255*f88698d6SMark Rutland * default as some ARM machines do not support it.
2569a1bc9eaSIan Rogers */
2579a1bc9eaSIan Rogers evsel->core.attr.exclude_kernel = 1;
2589a1bc9eaSIan Rogers ret = evsel__open(evsel, NULL, tmap) >= 0;
2599a1bc9eaSIan Rogers }
260*f88698d6SMark Rutland
261*f88698d6SMark Rutland if (!ret) {
262*f88698d6SMark Rutland /*
263*f88698d6SMark Rutland * The event may fail to open if the PMU requires
264*f88698d6SMark Rutland * exclude_guest to be set (e.g. as the Apple M1 PMU
265*f88698d6SMark Rutland * requires).
266*f88698d6SMark Rutland * Re-run with exclude_guest set; we don't do that by
267*f88698d6SMark Rutland * default as it's equally legitimate for another PMU
268*f88698d6SMark Rutland * driver to require that exclude_guest is clear.
269*f88698d6SMark Rutland */
270*f88698d6SMark Rutland evsel->core.attr.exclude_guest = 1;
271*f88698d6SMark Rutland ret = evsel__open(evsel, NULL, tmap) >= 0;
272*f88698d6SMark Rutland }
273*f88698d6SMark Rutland
2749a1bc9eaSIan Rogers evsel__delete(evsel);
2759a1bc9eaSIan Rogers }
2769a1bc9eaSIan Rogers
2779a1bc9eaSIan Rogers perf_thread_map__put(tmap);
2789a1bc9eaSIan Rogers return ret;
2799a1bc9eaSIan Rogers }
2809a1bc9eaSIan Rogers
print_hwcache_events(const struct print_callbacks * print_cb,void * print_state)281e5c6109fSIan Rogers int print_hwcache_events(const struct print_callbacks *print_cb, void *print_state)
2829b7c7728SIan Rogers {
283d7f21df0SIan Rogers struct perf_pmu *pmu = NULL;
284442eeb77SIan Rogers const char *event_type_descriptor = event_type_descriptors[PERF_TYPE_HW_CACHE];
2859b7c7728SIan Rogers
286d7f21df0SIan Rogers /*
2879d6a1df9SIan Rogers * Only print core PMUs, skipping uncore for performance and
2889d6a1df9SIan Rogers * PERF_TYPE_SOFTWARE that can succeed in opening legacy cache evenst.
289d7f21df0SIan Rogers */
2909d6a1df9SIan Rogers while ((pmu = perf_pmus__scan_core(pmu)) != NULL) {
291d7f21df0SIan Rogers if (pmu->is_uncore || pmu->type == PERF_TYPE_SOFTWARE)
292d7f21df0SIan Rogers continue;
293d7f21df0SIan Rogers
2943301b3feSIan Rogers for (int type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
2953301b3feSIan Rogers for (int op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
2969b7c7728SIan Rogers /* skip invalid cache type */
2979b7c7728SIan Rogers if (!evsel__is_cache_op_valid(type, op))
2989b7c7728SIan Rogers continue;
2999b7c7728SIan Rogers
300442eeb77SIan Rogers for (int res = 0; res < PERF_COUNT_HW_CACHE_RESULT_MAX; res++) {
3013301b3feSIan Rogers char name[64];
302d7f21df0SIan Rogers char alias_name[128];
303d7f21df0SIan Rogers __u64 config;
304d7f21df0SIan Rogers int ret;
3059b7c7728SIan Rogers
306442eeb77SIan Rogers __evsel__hw_cache_type_op_res_name(type, op, res,
307442eeb77SIan Rogers name, sizeof(name));
308d7f21df0SIan Rogers
309d7f21df0SIan Rogers ret = parse_events__decode_legacy_cache(name, pmu->type,
310d7f21df0SIan Rogers &config);
311d7f21df0SIan Rogers if (ret || !is_event_supported(PERF_TYPE_HW_CACHE, config))
312442eeb77SIan Rogers continue;
313d7f21df0SIan Rogers snprintf(alias_name, sizeof(alias_name), "%s/%s/",
314d7f21df0SIan Rogers pmu->name, name);
315442eeb77SIan Rogers print_cb->print_event(print_state,
316442eeb77SIan Rogers "cache",
317442eeb77SIan Rogers pmu->name,
318442eeb77SIan Rogers name,
319d7f21df0SIan Rogers alias_name,
320442eeb77SIan Rogers /*scale_unit=*/NULL,
321442eeb77SIan Rogers /*deprecated=*/false,
322442eeb77SIan Rogers event_type_descriptor,
323442eeb77SIan Rogers /*desc=*/NULL,
324442eeb77SIan Rogers /*long_desc=*/NULL,
325442eeb77SIan Rogers /*encoding_desc=*/NULL);
326442eeb77SIan Rogers }
327442eeb77SIan Rogers }
328442eeb77SIan Rogers }
329442eeb77SIan Rogers }
3303301b3feSIan Rogers return 0;
3319b7c7728SIan Rogers }
3329b7c7728SIan Rogers
print_tool_events(const struct print_callbacks * print_cb,void * print_state)333e5c6109fSIan Rogers void print_tool_events(const struct print_callbacks *print_cb, void *print_state)
3349b7c7728SIan Rogers {
3359b7c7728SIan Rogers // Start at 1 because the first enum entry means no tool event.
336e5c6109fSIan Rogers for (int i = 1; i < PERF_TOOL_MAX; ++i) {
337e5c6109fSIan Rogers print_cb->print_event(print_state,
338e5c6109fSIan Rogers "tool",
339e5c6109fSIan Rogers /*pmu_name=*/NULL,
340e5c6109fSIan Rogers event_symbols_tool[i].symbol,
341e5c6109fSIan Rogers event_symbols_tool[i].alias,
342e5c6109fSIan Rogers /*scale_unit=*/NULL,
343e5c6109fSIan Rogers /*deprecated=*/false,
344e5c6109fSIan Rogers "Tool event",
345e5c6109fSIan Rogers /*desc=*/NULL,
346e5c6109fSIan Rogers /*long_desc=*/NULL,
347d9dc8874SIan Rogers /*encoding_desc=*/NULL);
348e5c6109fSIan Rogers }
3499b7c7728SIan Rogers }
3509b7c7728SIan Rogers
print_symbol_events(const struct print_callbacks * print_cb,void * print_state,unsigned int type,const struct event_symbol * syms,unsigned int max)351e5c6109fSIan Rogers void print_symbol_events(const struct print_callbacks *print_cb, void *print_state,
352e5c6109fSIan Rogers unsigned int type, const struct event_symbol *syms,
353e5c6109fSIan Rogers unsigned int max)
3549b7c7728SIan Rogers {
355de3752a7SIan Rogers struct strlist *evt_name_list = strlist__new(NULL, NULL);
356de3752a7SIan Rogers struct str_node *nd;
3579b7c7728SIan Rogers
358de3752a7SIan Rogers if (!evt_name_list) {
359de3752a7SIan Rogers pr_debug("Failed to allocate new strlist for symbol events\n");
360de3752a7SIan Rogers return;
3619b7c7728SIan Rogers }
362de3752a7SIan Rogers for (unsigned int i = 0; i < max; i++) {
3639b7c7728SIan Rogers /*
3649b7c7728SIan Rogers * New attr.config still not supported here, the latest
3659b7c7728SIan Rogers * example was PERF_COUNT_SW_CGROUP_SWITCHES
3669b7c7728SIan Rogers */
367de3752a7SIan Rogers if (syms[i].symbol == NULL)
3689b7c7728SIan Rogers continue;
3699b7c7728SIan Rogers
3709b7c7728SIan Rogers if (!is_event_supported(type, i))
3719b7c7728SIan Rogers continue;
3729b7c7728SIan Rogers
373de3752a7SIan Rogers if (strlen(syms[i].alias)) {
374de3752a7SIan Rogers char name[MAX_NAME_LEN];
375de3752a7SIan Rogers
376de3752a7SIan Rogers snprintf(name, MAX_NAME_LEN, "%s OR %s", syms[i].symbol, syms[i].alias);
377de3752a7SIan Rogers strlist__add(evt_name_list, name);
378de3752a7SIan Rogers } else
379de3752a7SIan Rogers strlist__add(evt_name_list, syms[i].symbol);
3809b7c7728SIan Rogers }
3819b7c7728SIan Rogers
382de3752a7SIan Rogers strlist__for_each_entry(nd, evt_name_list) {
383e5c6109fSIan Rogers char *alias = strstr(nd->s, " OR ");
3849b7c7728SIan Rogers
385e5c6109fSIan Rogers if (alias) {
386e5c6109fSIan Rogers *alias = '\0';
387e5c6109fSIan Rogers alias += 4;
388e5c6109fSIan Rogers }
389e5c6109fSIan Rogers print_cb->print_event(print_state,
390e5c6109fSIan Rogers /*topic=*/NULL,
391e5c6109fSIan Rogers /*pmu_name=*/NULL,
392e5c6109fSIan Rogers nd->s,
393e5c6109fSIan Rogers alias,
394e5c6109fSIan Rogers /*scale_unit=*/NULL,
395e5c6109fSIan Rogers /*deprecated=*/false,
396e5c6109fSIan Rogers event_type_descriptors[type],
397e5c6109fSIan Rogers /*desc=*/NULL,
398e5c6109fSIan Rogers /*long_desc=*/NULL,
399d9dc8874SIan Rogers /*encoding_desc=*/NULL);
400e5c6109fSIan Rogers }
401de3752a7SIan Rogers strlist__delete(evt_name_list);
4029b7c7728SIan Rogers }
4039b7c7728SIan Rogers
4049b7c7728SIan Rogers /*
4059b7c7728SIan Rogers * Print the help text for the event symbols:
4069b7c7728SIan Rogers */
print_events(const struct print_callbacks * print_cb,void * print_state)407e5c6109fSIan Rogers void print_events(const struct print_callbacks *print_cb, void *print_state)
4089b7c7728SIan Rogers {
409e5c6109fSIan Rogers print_symbol_events(print_cb, print_state, PERF_TYPE_HARDWARE,
410e5c6109fSIan Rogers event_symbols_hw, PERF_COUNT_HW_MAX);
411e5c6109fSIan Rogers print_symbol_events(print_cb, print_state, PERF_TYPE_SOFTWARE,
412e5c6109fSIan Rogers event_symbols_sw, PERF_COUNT_SW_MAX);
4139b7c7728SIan Rogers
414e5c6109fSIan Rogers print_tool_events(print_cb, print_state);
4159b7c7728SIan Rogers
416e5c6109fSIan Rogers print_hwcache_events(print_cb, print_state);
4179b7c7728SIan Rogers
4181eaf496eSIan Rogers perf_pmus__print_pmu_events(print_cb, print_state);
4199b7c7728SIan Rogers
420e5c6109fSIan Rogers print_cb->print_event(print_state,
421e5c6109fSIan Rogers /*topic=*/NULL,
422e5c6109fSIan Rogers /*pmu_name=*/NULL,
4239b7c7728SIan Rogers "rNNN",
424e5c6109fSIan Rogers /*event_alias=*/NULL,
425e5c6109fSIan Rogers /*scale_unit=*/NULL,
426e5c6109fSIan Rogers /*deprecated=*/false,
427e5c6109fSIan Rogers event_type_descriptors[PERF_TYPE_RAW],
428e5c6109fSIan Rogers /*desc=*/NULL,
429e5c6109fSIan Rogers /*long_desc=*/NULL,
430d9dc8874SIan Rogers /*encoding_desc=*/NULL);
431e5c6109fSIan Rogers
432e5c6109fSIan Rogers print_cb->print_event(print_state,
433e5c6109fSIan Rogers /*topic=*/NULL,
434e5c6109fSIan Rogers /*pmu_name=*/NULL,
4359b7c7728SIan Rogers "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
436e5c6109fSIan Rogers /*event_alias=*/NULL,
437e5c6109fSIan Rogers /*scale_unit=*/NULL,
438e5c6109fSIan Rogers /*deprecated=*/false,
439e5c6109fSIan Rogers event_type_descriptors[PERF_TYPE_RAW],
440e5c6109fSIan Rogers "(see 'man perf-list' on how to encode it)",
441e5c6109fSIan Rogers /*long_desc=*/NULL,
442d9dc8874SIan Rogers /*encoding_desc=*/NULL);
4439b7c7728SIan Rogers
444e5c6109fSIan Rogers print_cb->print_event(print_state,
445e5c6109fSIan Rogers /*topic=*/NULL,
446e5c6109fSIan Rogers /*pmu_name=*/NULL,
4479b7c7728SIan Rogers "mem:<addr>[/len][:access]",
448e5c6109fSIan Rogers /*scale_unit=*/NULL,
449e5c6109fSIan Rogers /*event_alias=*/NULL,
450e5c6109fSIan Rogers /*deprecated=*/false,
451e5c6109fSIan Rogers event_type_descriptors[PERF_TYPE_BREAKPOINT],
452e5c6109fSIan Rogers /*desc=*/NULL,
453e5c6109fSIan Rogers /*long_desc=*/NULL,
454d9dc8874SIan Rogers /*encoding_desc=*/NULL);
4559b7c7728SIan Rogers
456e5c6109fSIan Rogers print_tracepoint_events(print_cb, print_state);
4579b7c7728SIan Rogers
458e5c6109fSIan Rogers print_sdt_events(print_cb, print_state);
4599b7c7728SIan Rogers
460e5c6109fSIan Rogers metricgroup__print(print_cb, print_state);
4619b7c7728SIan Rogers
462e5c6109fSIan Rogers print_libpfm_events(print_cb, print_state);
4639b7c7728SIan Rogers }
464