summaryrefslogtreecommitdiff
path: root/tools/perf/util/trace-event-info.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/trace-event-info.c')
-rw-r--r--tools/perf/util/trace-event-info.c173
1 files changed, 129 insertions, 44 deletions
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index 8ad8e755127b..c8755679281e 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -1,24 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2008,2009, Steven Rostedt <srostedt@redhat.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License (not later!)
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-#include "util.h"
#include <dirent.h>
#include <mntent.h>
#include <stdio.h>
@@ -34,26 +17,27 @@
#include <stdbool.h>
#include <linux/list.h>
#include <linux/kernel.h>
+#include <linux/zalloc.h>
+#include <internal/lib.h> // page_size
+#include <sys/param.h>
-#include "../perf.h"
#include "trace-event.h"
+#include "tracepoint.h"
#include <api/fs/tracing_path.h>
#include "evsel.h"
#include "debug.h"
+#include "util.h"
#define VERSION "0.6"
+#define MAX_EVENT_LENGTH 512
static int output_fd;
-
-int bigendian(void)
-{
- unsigned char str[] = { 0x1, 0x2, 0x3, 0x4, 0x0, 0x0, 0x0, 0x0};
- unsigned int *ptr;
-
- ptr = (unsigned int *)(void *)str;
- return *ptr == 0x01020304;
-}
+struct tracepoint_path {
+ char *system;
+ char *name;
+ struct tracepoint_path *next;
+};
/* unfortunately, you can not stat debugfs or proc files for size */
static int record_file(const char *file, ssize_t hdr_sz)
@@ -87,7 +71,7 @@ static int record_file(const char *file, ssize_t hdr_sz)
/* ugh, handle big-endian hdr_size == 4 */
sizep = (char*)&size;
- if (bigendian())
+ if (host_is_bigendian())
sizep += sizeof(u64) - hdr_sz;
if (hdr_sz && pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0) {
@@ -168,7 +152,7 @@ static bool name_in_tp_list(char *sys, struct tracepoint_path *tps)
return false;
}
-#define for_each_event(dir, dent, tps) \
+#define for_each_event_tps(dir, dent, tps) \
while ((dent = readdir(dir))) \
if (dent->d_type == DT_DIR && \
(strcmp(dent->d_name, ".")) && \
@@ -190,7 +174,7 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps)
return -errno;
}
- for_each_event(dir, dent, tps) {
+ for_each_event_tps(dir, dent, tps) {
if (!name_in_tp_list(dent->d_name, tps))
continue;
@@ -212,7 +196,7 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps)
}
rewinddir(dir);
- for_each_event(dir, dent, tps) {
+ for_each_event_tps(dir, dent, tps) {
if (!name_in_tp_list(dent->d_name, tps))
continue;
@@ -290,7 +274,7 @@ static int record_event_files(struct tracepoint_path *tps)
goto out;
}
- for_each_event(dir, dent, tps) {
+ for_each_event_tps(dir, dent, tps) {
if (strcmp(dent->d_name, "ftrace") == 0 ||
!system_in_tp_list(dent->d_name, tps))
continue;
@@ -305,7 +289,7 @@ static int record_event_files(struct tracepoint_path *tps)
}
rewinddir(dir);
- for_each_event(dir, dent, tps) {
+ for_each_event_tps(dir, dent, tps) {
if (strcmp(dent->d_name, "ftrace") == 0 ||
!system_in_tp_list(dent->d_name, tps))
continue;
@@ -329,7 +313,8 @@ static int record_event_files(struct tracepoint_path *tps)
}
err = 0;
out:
- closedir(dir);
+ if (dir)
+ closedir(dir);
put_tracing_file(path);
return err;
@@ -416,15 +401,115 @@ put_tracepoints_path(struct tracepoint_path *tps)
}
}
+static struct tracepoint_path *tracepoint_id_to_path(u64 config)
+{
+ struct tracepoint_path *path = NULL;
+ DIR *sys_dir, *evt_dir;
+ struct dirent *sys_dirent, *evt_dirent;
+ char id_buf[24];
+ int fd;
+ u64 id;
+ char evt_path[MAXPATHLEN];
+ char *dir_path;
+
+ sys_dir = tracing_events__opendir();
+ if (!sys_dir)
+ return NULL;
+
+ for_each_subsystem(sys_dir, sys_dirent) {
+ dir_path = get_events_file(sys_dirent->d_name);
+ if (!dir_path)
+ continue;
+ evt_dir = opendir(dir_path);
+ if (!evt_dir)
+ goto next;
+
+ for_each_event(dir_path, evt_dir, evt_dirent) {
+
+ scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path,
+ evt_dirent->d_name);
+ fd = open(evt_path, O_RDONLY);
+ if (fd < 0)
+ continue;
+ if (read(fd, id_buf, sizeof(id_buf)) < 0) {
+ close(fd);
+ continue;
+ }
+ close(fd);
+ id = atoll(id_buf);
+ if (id == config) {
+ put_events_file(dir_path);
+ closedir(evt_dir);
+ closedir(sys_dir);
+ path = zalloc(sizeof(*path));
+ if (!path)
+ return NULL;
+ if (asprintf(&path->system, "%.*s",
+ MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) {
+ free(path);
+ return NULL;
+ }
+ if (asprintf(&path->name, "%.*s",
+ MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) {
+ zfree(&path->system);
+ free(path);
+ return NULL;
+ }
+ return path;
+ }
+ }
+ closedir(evt_dir);
+next:
+ put_events_file(dir_path);
+ }
+
+ closedir(sys_dir);
+ return NULL;
+}
+
+char *tracepoint_id_to_name(u64 config)
+{
+ struct tracepoint_path *path = tracepoint_id_to_path(config);
+ char *buf = NULL;
+
+ if (path && asprintf(&buf, "%s:%s", path->system, path->name) < 0)
+ buf = NULL;
+
+ put_tracepoints_path(path);
+ return buf;
+}
+
+static struct tracepoint_path *tracepoint_name_to_path(const char *name)
+{
+ struct tracepoint_path *path = zalloc(sizeof(*path));
+ char *str = strchr(name, ':');
+
+ if (path == NULL || str == NULL) {
+ free(path);
+ return NULL;
+ }
+
+ path->system = strndup(name, str - name);
+ path->name = strdup(str+1);
+
+ if (path->system == NULL || path->name == NULL) {
+ zfree(&path->system);
+ zfree(&path->name);
+ zfree(&path);
+ }
+
+ return path;
+}
+
static struct tracepoint_path *
get_tracepoints_path(struct list_head *pattrs)
{
struct tracepoint_path path, *ppath = &path;
- struct perf_evsel *pos;
+ struct evsel *pos;
int nr_tracepoints = 0;
- list_for_each_entry(pos, pattrs, node) {
- if (pos->attr.type != PERF_TYPE_TRACEPOINT)
+ list_for_each_entry(pos, pattrs, core.node) {
+ if (pos->core.attr.type != PERF_TYPE_TRACEPOINT)
continue;
++nr_tracepoints;
@@ -440,11 +525,11 @@ get_tracepoints_path(struct list_head *pattrs)
}
try_id:
- ppath->next = tracepoint_id_to_path(pos->attr.config);
+ ppath->next = tracepoint_id_to_path(pos->core.attr.config);
if (!ppath->next) {
error:
pr_debug("No memory to alloc tracepoints list\n");
- put_tracepoints_path(&path);
+ put_tracepoints_path(path.next);
return NULL;
}
next:
@@ -456,10 +541,10 @@ next:
bool have_tracepoints(struct list_head *pattrs)
{
- struct perf_evsel *pos;
+ struct evsel *pos;
- list_for_each_entry(pos, pattrs, node)
- if (pos->attr.type == PERF_TYPE_TRACEPOINT)
+ list_for_each_entry(pos, pattrs, core.node)
+ if (pos->core.attr.type == PERF_TYPE_TRACEPOINT)
return true;
return false;
@@ -484,7 +569,7 @@ static int tracing_data_header(void)
return -1;
/* save endian */
- if (bigendian())
+ if (host_is_bigendian())
buf[0] = 1;
else
buf[0] = 0;