[PATCH 17/20] perf: Export trace parsing utils

Borislav Petkov
2010-11-04T15:40:51Z

.. and put them into lib/trace/ for a wider use. Also, move a couple of
helpers from perf/util/parse-events.c -> lib/trace/trace-event-info.c.
While at it, merge duplicated enum trace_flag_type.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
tools/lib/lk/debugfs.c | 1 +
tools/lib/lk/debugfs.h | 1 +
tools/lib/trace/Makefile | 7 +-
tools/lib/trace/parse-events.h | 12 +-
tools/lib/trace/trace-event-info.c | 650 ++++++++++++++++++++
tools/lib/trace/trace-event-parse.c | 231 +++++++
tools/lib/trace/trace-event-read.c | 541 ++++++++++++++++
tools/lib/trace/trace-event.h | 115 ++++
tools/perf/Makefile | 4 -
tools/perf/builtin-kmem.c | 2 +-
tools/perf/builtin-kvm.c | 2 +-
tools/perf/builtin-lock.c | 2 +-
tools/perf/builtin-sched.c | 2 +-
tools/perf/builtin-timechart.c | 19 -
tools/perf/builtin-trace.c | 2 +-
tools/perf/scripts/perl/Perf-Trace-Util/Context.c | 2 +-
tools/perf/scripts/perl/Perf-Trace-Util/Context.xs | 2 +-
.../perf/scripts/python/Perf-Trace-Util/Context.c | 2 +-
tools/perf/util/header.c | 7 +-
tools/perf/util/parse-events.c | 103 +---
tools/perf/util/parse-events.h | 9 +-
tools/perf/util/probe-event.c | 2 +-
.../perf/util/scripting-engines/trace-event-perl.c | 2 +-
.../util/scripting-engines/trace-event-python.c | 2 +-
tools/perf/util/trace-event-info.c | 566 -----------------
tools/perf/util/trace-event-parse.c | 234 -------
tools/perf/util/trace-event-read.c | 541 ----------------
tools/perf/util/trace-event-scripting.c | 2 +-
tools/perf/util/trace-event.h | 90 ---
29 files changed, 1574 insertions(+), 1581 deletions(-)
create mode 100644 tools/lib/trace/trace-event-info.c
create mode 100644 tools/lib/trace/trace-event-parse.c
create mode 100644 tools/lib/trace/trace-event-read.c
create mode 100644 tools/lib/trace/trace-event.h
delete mode 100644 tools/perf/util/trace-event-info.c
delete mode 100644 tools/perf/util/trace-event-parse.c
delete mode 100644 tools/perf/util/trace-event-read.c
delete mode 100644 tools/perf/util/trace-event.h

diff --git a/tools/lib/lk/debugfs.c b/tools/lib/lk/debugfs.c
index c4e7ffe..6920cf9 100644
--- a/tools/lib/lk/debugfs.c
+++ b/tools/lib/lk/debugfs.c
@@ -7,6 +7,7 @@
static int debugfs_premounted;
static char debugfs_mountpoint[MAX_PATH+1];
char debugfs_mntpt[MAXPATHLEN];
+char debugfs_path[MAXPATHLEN];

static const char *debugfs_known_mountpoints[] = {
"/sys/kernel/debug/",
diff --git a/tools/lib/lk/debugfs.h b/tools/lib/lk/debugfs.h
index 5970f0b..5590c43 100644
--- a/tools/lib/lk/debugfs.h
+++ b/tools/lib/lk/debugfs.h
@@ -16,6 +16,7 @@
#define LK_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"

extern char debugfs_mntpt[];
+extern char debugfs_path[];

extern const char *debugfs_find_mountpoint(void);
extern int debugfs_valid_mountpoint(const char *debugfs);
diff --git a/tools/lib/trace/Makefile b/tools/lib/trace/Makefile
index 22fa7b6..a0ca116 100644
--- a/tools/lib/trace/Makefile
+++ b/tools/lib/trace/Makefile
@@ -37,17 +37,22 @@ TRACE_LIB = $(LIB_OUTPUT)libparsevent.a

all: $(TRACE_LIB)

+PEVENT_LIB_H += trace-event.h
+
PEVENT_LIB_OBJS += parse-events.o
PEVENT_LIB_OBJS += parse-filter.o
PEVENT_LIB_OBJS += parse-utils.o
PEVENT_LIB_OBJS += trace-seq.o
+PEVENT_LIB_OBJS += trace-event-parse.o
+PEVENT_LIB_OBJS += trace-event-read.o
+PEVENT_LIB_OBJS += trace-event-info.o

ALL_CFLAGS = $(CFLAGS) $(BASIC_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64

$(OUTPUT)%.o: %.c
$(QUIET_CC)$(CC) -g -o $@ -c $(ALL_CFLAGS) $<

-$(TRACE_LIB): $(PEVENT_LIB_OBJS)
+$(TRACE_LIB): $(PEVENT_LIB_OBJS) $(PEVENT_LIB_H)
$(RM) $@; $(AR) rcs $@ $^

clean:
diff --git a/tools/lib/trace/parse-events.h b/tools/lib/trace/parse-events.h
index 31f46f5..f967885 100644
--- a/tools/lib/trace/parse-events.h
+++ b/tools/lib/trace/parse-events.h
@@ -425,7 +425,17 @@ __data2host8(struct pevent *pevent, unsigned long long data)
__data2host8(pevent, __val); \
})

-/* taken from kernel/trace/trace.h */
+/*
+ * trace_flag_type is an enumeration that holds different
+ * states when a trace occurs. These are:
+ * IRQS_OFF - interrupts were disabled
+ * IRQS_NOSUPPORT - arch does not support irqs_disabled_flags
+ * NEED_RESCED - reschedule is requested
+ * HARDIRQ - inside an interrupt handler
+ * SOFTIRQ - inside a softirq handler
+ *
+ * taken from kernel/trace/trace.h
+ */
enum trace_flag_type {
TRACE_FLAG_IRQS_OFF = 0x01,
TRACE_FLAG_IRQS_NOSUPPORT = 0x02,
diff --git a/tools/lib/trace/trace-event-info.c b/tools/lib/trace/trace-event-info.c
new file mode 100644
index 0000000..98faa44
--- /dev/null
+++ b/tools/lib/trace/trace-event-info.c
@@ -0,0 +1,650 @@
+/*
+ * 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
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#define _GNU_SOURCE
+#include <dirent.h>
+#include <mntent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <lk/util.h>
+#include <lk/kernel.h>
+#include <lk/debugfs.h>
+
+#include "../../perf/perf.h"
+#include "trace-event.h"
+
+#define VERSION "0.5"
+
+#define _STR(x) #x
+#define STR(x) _STR(x)
+#define MAX_PATH 256
+
+#define TRACE_CTRL "tracing_on"
+#define TRACE "trace"
+#define AVAILABLE "available_tracers"
+#define CURRENT "current_tracer"
+#define ITER_CTRL "trace_options"
+#define MAX_LATENCY "tracing_max_latency"
+
+unsigned int page_size;
+
+static const char *output_file = "trace.info";
+static int output_fd;
+
+struct event_list {
+ struct event_list *next;
+ const char *event;
+};
+
+struct events {
+ struct events *sibling;
+ struct events *children;
+ struct events *next;
+ char *name;
+};
+
+
+
+static void t_die(const char *fmt, ...)
+{
+ va_list ap;
+ int ret = errno;
+
+ if (errno)
+ perror("trace-cmd");
+ else
+ ret = -1;
+
+ va_start(ap, fmt);
+ fprintf(stderr, " ");
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ fprintf(stderr, "\n");
+ exit(ret);
+}
+
+void *malloc_or_die(unsigned int size)
+{
+ void *data;
+
+ data = malloc(size);
+ if (!data)
+ t_die("malloc");
+ return data;
+}
+
+static const char *find_debugfs(void)
+{
+ const char *path = debugfs_mount(NULL);
+
+ if (!path)
+ t_die("Your kernel not support debugfs filesystem");
+
+ return path;
+}
+
+/*
+ * Finds the path to the debugfs/tracing
+ * Allocates the string and stores it.
+ */
+static const char *find_tracing_dir(void)
+{
+ static char *tracing;
+ static int tracing_found;
+ const char *debugfs;
+
+ if (tracing_found)
+ return tracing;
+
+ debugfs = find_debugfs();
+
+ tracing = malloc_or_die(strlen(debugfs) + 9);
+
+ sprintf(tracing, "%s/tracing", debugfs);
+
+ tracing_found = 1;
+ return tracing;
+}
+
+static char *get_tracing_file(const char *name)
+{
+ const char *tracing;
+ char *file;
+
+ tracing = find_tracing_dir();
+ if (!tracing)
+ return NULL;
+
+ file = malloc_or_die(strlen(tracing) + strlen(name) + 2);
+
+ sprintf(file, "%s/%s", tracing, name);
+ return file;
+}
+
+static void put_tracing_file(char *file)
+{
+ free(file);
+}
+
+static ssize_t calc_data_size;
+
+static ssize_t write_or_die(const void *buf, size_t len)
+{
+ int ret;
+
+ if (calc_data_size) {
+ calc_data_size += len;
+ return len;
+ }
+
+ ret = write(output_fd, buf, len);
+ if (ret < 0)
+ t_die("writing to '%s'", output_file);
+
+ return ret;
+}
+
+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;
+}
+
+static unsigned long long copy_file_fd(int fd)
+{
+ unsigned long long size = 0;
+ char buf[BUFSIZ];
+ int r;
+
+ do {
+ r = read(fd, buf, BUFSIZ);
+ if (r > 0) {
+ size += r;
+ write_or_die(buf, r);
+ }
+ } while (r > 0);
+
+ return size;
+}
+
+static unsigned long long copy_file(const char *file)
+{
+ unsigned long long size = 0;
+ int fd;
+
+ fd = open(file, O_RDONLY);
+ if (fd < 0)
+ t_die("Can't read '%s'", file);
+ size = copy_file_fd(fd);
+ close(fd);
+
+ return size;
+}
+
+static unsigned long get_size_fd(int fd)
+{
+ unsigned long long size = 0;
+ char buf[BUFSIZ];
+ int r;
+
+ do {
+ r = read(fd, buf, BUFSIZ);
+ if (r > 0)
+ size += r;
+ } while (r > 0);
+
+ lseek(fd, 0, SEEK_SET);
+
+ return size;
+}
+
+static unsigned long get_size(const char *file)
+{
+ unsigned long long size = 0;
+ int fd;
+
+ fd = open(file, O_RDONLY);
+ if (fd < 0)
+ t_die("Can't read '%s'", file);
+ size = get_size_fd(fd);
+ close(fd);
+
+ return size;
+}
+
+static void read_header_files(void)
+{
+ unsigned long long size, check_size;
+ char *path;
+ int fd;
+
+ path = get_tracing_file("events/header_page");
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ t_die("can't read '%s'", path);
+
+ /* unfortunately, you can not stat debugfs files for size */
+ size = get_size_fd(fd);
+
+ write_or_die("header_page", 12);
+ write_or_die(&size, 8);
+ check_size = copy_file_fd(fd);
+ close(fd);
+
+ if (size != check_size)
+ t_die("wrong size for '%s' size=%lld read=%lld",
+ path, size, check_size);
+ put_tracing_file(path);
+
+ path = get_tracing_file("events/header_event");
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ t_die("can't read '%s'", path);
+
+ size = get_size_fd(fd);
+
+ write_or_die("header_event", 13);
+ write_or_die(&size, 8);
+ check_size = copy_file_fd(fd);
+ if (size != check_size)
+ t_die("wrong size for '%s'", path);
+ put_tracing_file(path);
+ close(fd);
+}
+
+static bool name_in_tp_list(char *sys, struct tracepoint_path *tps)
+{
+ while (tps) {
+ if (!strcmp(sys, tps->name))
+ return true;
+ tps = tps->next;
+ }
+
+ return false;
+}
+
+static void copy_event_system(const char *sys, struct tracepoint_path *tps)
+{
+ unsigned long long size, check_size;
+ struct dirent *dent;
+ struct stat st;
+ char *format;
+ DIR *dir;
+ int count = 0;
+ int ret;
+
+ dir = opendir(sys);
+ if (!dir)
+ t_die("can't read directory '%s'", sys);
+
+ while ((dent = readdir(dir))) {
+ if (dent->d_type != DT_DIR ||
+ strcmp(dent->d_name, ".") == 0 ||
+ strcmp(dent->d_name, "..") == 0 ||
+ !name_in_tp_list(dent->d_name, tps))
+ continue;
+ format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10);
+ sprintf(format, "%s/%s/format", sys, dent->d_name);
+ ret = stat(format, &st);
+ free(format);
+ if (ret < 0)
+ continue;
+ count++;
+ }
+
+ write_or_die(&count, 4);
+
+ rewinddir(dir);
+ while ((dent = readdir(dir))) {
+ if (dent->d_type != DT_DIR ||
+ strcmp(dent->d_name, ".") == 0 ||
+ strcmp(dent->d_name, "..") == 0 ||
+ !name_in_tp_list(dent->d_name, tps))
+ continue;
+ format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10);
+ sprintf(format, "%s/%s/format", sys, dent->d_name);
+ ret = stat(format, &st);
+
+ if (ret >= 0) {
+ /* unfortunately, you can not stat debugfs files for size */
+ size = get_size(format);
+ write_or_die(&size, 8);
+ check_size = copy_file(format);
+ if (size != check_size)
+ t_die("error in size of file '%s'", format);
+ }
+
+ free(format);
+ }
+ closedir(dir);
+}
+
+static void read_ftrace_files(struct tracepoint_path *tps)
+{
+ char *path;
+
+ path = get_tracing_file("events/ftrace");
+
+ copy_event_system(path, tps);
+
+ put_tracing_file(path);
+}
+
+static bool system_in_tp_list(char *sys, struct tracepoint_path *tps)
+{
+ while (tps) {
+ if (!strcmp(sys, tps->system))
+ return true;
+ tps = tps->next;
+ }
+
+ return false;
+}
+
+static void read_event_files(struct tracepoint_path *tps)
+{
+ struct dirent *dent;
+ struct stat st;
+ char *path;
+ char *sys;
+ DIR *dir;
+ int count = 0;
+ int ret;
+
+ path = get_tracing_file("events");
+
+ dir = opendir(path);
+ if (!dir)
+ t_die("can't read directory '%s'", path);
+
+ while ((dent = readdir(dir))) {
+ if (dent->d_type != DT_DIR ||
+ strcmp(dent->d_name, ".") == 0 ||
+ strcmp(dent->d_name, "..") == 0 ||
+ strcmp(dent->d_name, "ftrace") == 0 ||
+ !system_in_tp_list(dent->d_name, tps))
+ continue;
+ count++;
+ }
+
+ write_or_die(&count, 4);
+
+ rewinddir(dir);
+ while ((dent = readdir(dir))) {
+ if (dent->d_type != DT_DIR ||
+ strcmp(dent->d_name, ".") == 0 ||
+ strcmp(dent->d_name, "..") == 0 ||
+ strcmp(dent->d_name, "ftrace") == 0 ||
+ !system_in_tp_list(dent->d_name, tps))
+ continue;
+ sys = malloc_or_die(strlen(path) + strlen(dent->d_name) + 2);
+ sprintf(sys, "%s/%s", path, dent->d_name);
+ ret = stat(sys, &st);
+ if (ret >= 0) {
+ write_or_die(dent->d_name, strlen(dent->d_name) + 1);
+ copy_event_system(sys, tps);
+ }
+ free(sys);
+ }
+
+ closedir(dir);
+ put_tracing_file(path);
+}
+
+static void read_proc_kallsyms(void)
+{
+ unsigned int size, check_size;
+ const char *path = "/proc/kallsyms";
+ struct stat st;
+ int ret;
+
+ ret = stat(path, &st);
+ if (ret < 0) {
+ /* not found */
+ size = 0;
+ write_or_die(&size, 4);
+ return;
+ }
+ size = get_size(path);
+ write_or_die(&size, 4);
+ check_size = copy_file(path);
+ if (size != check_size)
+ t_die("error in size of file '%s'", path);
+
+}
+
+static void read_ftrace_printk(void)
+{
+ unsigned int size, check_size;
+ char *path;
+ struct stat st;
+ int ret;
+
+ path = get_tracing_file("printk_formats");
+ ret = stat(path, &st);
+ if (ret < 0) {
+ /* not found */
+ size = 0;
+ write_or_die(&size, 4);
+ goto out;
+ }
+ size = get_size(path);
+ write_or_die(&size, 4);
+ check_size = copy_file(path);
+ if (size != check_size)
+ t_die("error in size of file '%s'", path);
+out:
+ put_tracing_file(path);
+}
+
+int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
+{
+ char evt_path[MAXPATHLEN];
+ int fd;
+
+ snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path,
+ sys_dir->d_name, evt_dir->d_name);
+ fd = open(evt_path, O_RDONLY);
+ if (fd < 0)
+ return -EINVAL;
+ close(fd);
+
+ return 0;
+}
+
+struct tracepoint_path *tracepoint_id_to_path(u64 config)
+{
+ struct tracepoint_path *path = NULL;
+ DIR *sys_dir, *evt_dir;
+ struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
+ char id_buf[4];
+ int fd;
+ u64 id;
+ char evt_path[MAXPATHLEN];
+ char dir_path[MAXPATHLEN];
+
+ if (debugfs_valid_mountpoint(debugfs_path))
+ return NULL;
+
+ sys_dir = opendir(debugfs_path);
+ if (!sys_dir)
+ return NULL;
+
+ for_each_subsystem(sys_dir, sys_dirent, sys_next) {
+
+ snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
+ sys_dirent.d_name);
+ evt_dir = opendir(dir_path);
+ if (!evt_dir)
+ continue;
+
+ for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
+
+ snprintf(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) {
+ closedir(evt_dir);
+ closedir(sys_dir);
+ path = zalloc(sizeof(*path));
+ path->system = malloc(MAX_EVENT_LENGTH);
+ if (!path->system) {
+ free(path);
+ return NULL;
+ }
+ path->name = malloc(MAX_EVENT_LENGTH);
+ if (!path->name) {
+ free(path->system);
+ free(path);
+ return NULL;
+ }
+ strncpy(path->system, sys_dirent.d_name,
+ MAX_EVENT_LENGTH);
+ strncpy(path->name, evt_dirent.d_name,
+ MAX_EVENT_LENGTH);
+ return path;
+ }
+ }
+ closedir(evt_dir);
+ }
+
+ closedir(sys_dir);
+ return NULL;
+}
+
+static struct tracepoint_path *
+get_tracepoints_path(struct perf_event_attr *pattrs, int nb_events)
+{
+ struct tracepoint_path path, *ppath = &path;
+ int i, nr_tracepoints = 0;
+
+ for (i = 0; i < nb_events; i++) {
+ if (pattrs[i].type != PERF_TYPE_TRACEPOINT)
+ continue;
+ ++nr_tracepoints;
+ ppath->next = tracepoint_id_to_path(pattrs[i].config);
+ if (!ppath->next)
+ t_die("%s\n", "No memory to alloc tracepoints list");
+ ppath = ppath->next;
+ }
+
+ return nr_tracepoints > 0 ? path.next : NULL;
+}
+
+bool have_tracepoints(struct perf_event_attr *pattrs, int nb_events)
+{
+ int i;
+
+ for (i = 0; i < nb_events; i++)
+ if (pattrs[i].type == PERF_TYPE_TRACEPOINT)
+ return true;
+
+ return false;
+}
+
+int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events)
+{
+ char buf[BUFSIZ];
+ struct tracepoint_path *tps = get_tracepoints_path(pattrs, nb_events);
+
+ /*
+ * What? No tracepoints? No sense writing anything here, bail out.
+ */
+ if (tps == NULL)
+ return -1;
+
+ output_fd = fd;
+
+ buf[0] = 23;
+ buf[1] = 8;
+ buf[2] = 68;
+ memcpy(buf + 3, "tracing", 7);
+
+ write_or_die(buf, 10);
+
+ write_or_die(VERSION, strlen(VERSION) + 1);
+
+ /* save endian */
+ if (bigendian())
+ buf[0] = 1;
+ else
+ buf[0] = 0;
+
+ read_trace_init(buf[0], buf[0]);
+
+ write_or_die(buf, 1);
+
+ /* save size of long */
+ buf[0] = sizeof(long);
+ write_or_die(buf, 1);
+
+ /* save page_size */
+ page_size = sysconf(_SC_PAGESIZE);
+ write_or_die(&page_size, 4);
+
+ read_header_files();
+ read_ftrace_files(tps);
+ read_event_files(tps);
+ read_proc_kallsyms();
+ read_ftrace_printk();
+
+ return 0;
+}
+
+ssize_t read_tracing_data_size(int fd, struct perf_event_attr *pattrs,
+ int nb_events)
+{
+ ssize_t size;
+ int err = 0;
+
+ calc_data_size = 1;
+ err = read_tracing_data(fd, pattrs, nb_events);
+ size = calc_data_size - 1;
+ calc_data_size = 0;
+
+ if (err < 0)
+ return err;
+
+ return size;
+}
diff --git a/tools/lib/trace/trace-event-parse.c b/tools/lib/trace/trace-event-parse.c
new file mode 100644
index 0000000..c6f77c9
--- /dev/null
+++ b/tools/lib/trace/trace-event-parse.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 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
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#undef _GNU_SOURCE
+#include "../../perf/perf.h"
+#include <lk/util.h>
+#include "trace-event.h"
+
+int header_page_size_size;
+int header_page_ts_size;
+int header_page_data_offset;
+
+struct pevent *perf_pevent;
+static struct pevent *pevent;
+
+bool latency_format;
+
+int read_trace_init(int file_bigendian, int host_bigendian)
+{
+ if (pevent)
+ return 0;
+
+ perf_pevent = pevent_alloc();
+ pevent = perf_pevent;
+
+ pevent_set_file_bigendian(pevent, file_bigendian);
+ pevent_set_host_bigendian(pevent, host_bigendian);
+
+ return 0;
+}
+
+unsigned long long
+raw_field_value(struct event_format *event, const char *name, void *data)
+{
+ struct format_field *field;
+ unsigned long long val;
+
+ field = pevent_find_any_field(event, name);
+ if (!field)
+ return 0ULL;
+
+ pevent_read_number_field(field, data, &val);
+
+ return val;
+}
+
+void *raw_field_ptr(struct event_format *event, const char *name, void *data)
+{
+ struct format_field *field;
+
+ field = pevent_find_any_field(event, name);
+ if (!field)
+ return NULL;
+
+ if (field->flags & FIELD_IS_DYNAMIC) {
+ int offset;
+
+ offset = *(int *)(data + field->offset);
+ offset &= 0xffff;
+
+ return data + offset;
+ }
+
+ return data + field->offset;
+}
+
+int trace_parse_common_type(void *data)
+{
+ struct record record;
+
+ record.data = data;
+ return pevent_data_type(pevent, &record);
+}
+
+struct event_format *trace_find_event(int type)
+{
+ return pevent_find_event(pevent, type);
+}
+
+void print_event(int cpu, void *data, int size, unsigned long long nsecs,
+ char *comm)
+{
+ struct record record;
+ struct trace_seq s;
+ int pid;
+
+ pevent->latency_format = latency_format;
+
+ record.ts = nsecs;
+ record.cpu = cpu;
+ record.size = size;
+ record.data = data;
+ pid = pevent_data_pid(pevent, &record);
+
+ if (!pevent_pid_is_registered(pevent, pid))
+ pevent_register_comm(pevent, comm, pid);
+
+ trace_seq_init(&s);
+ pevent_print_event(pevent, &s, &record);
+ trace_seq_do_printf(&s);
+ printf("\n");
+
+#if 0
+ struct event *event;
+ unsigned long secs;
+ unsigned long usecs;
+ int type;
+ int pid;
+
+ secs = nsecs / NSECS_PER_SEC;
+ nsecs -= secs * NSECS_PER_SEC;
+ usecs = nsecs / NSECS_PER_USEC;
+
+ type = trace_parse_common_type(data);
+
+ event = trace_find_event(type);
+ if (!event) {
+ warning("ug! no event found for type %d", type);
+ return;
+ }
+
+ pid = trace_parse_common_pid(data);
+
+ if (latency_format) {
+ printf("%8.8s-%-5d %3d",
+ comm, pid, cpu);
+ print_lat_fmt(data, size);
+ } else
+ printf("%16s-%-5d [%03d]", comm, pid, cpu);
+
+ printf(" %5lu.%06lu: %s: ", secs, usecs, event->name);
+
+ if (event->flags & EVENT_FL_FAILED) {
+ printf("EVENT '%s' FAILED TO PARSE\n",
+ event->name);
+ return;
+ }
+
+ pretty_print(data, size, event);
+ printf("\n");
+#endif
+}
+
+void parse_proc_kallsyms(char *file, unsigned int size __unused)
+{
+ unsigned long long addr;
+ char *func;
+ char *line;
+ char *next = NULL;
+ char *addr_str;
+ char *mod;
+ char ch;
+ int ret;
+
+ line = strtok_r(file, "\n", &next);
+ while (line) {
+ mod = NULL;
+ ret = sscanf(line, "%as %c %as\t[%as",
+ &addr_str, &ch, &func, &mod);
+ addr = strtoull(addr_str, NULL, 16);
+ free(addr_str);
+
+ /* truncate the extra ']' */
+ if (mod)
+ mod[strlen(mod) - 1] = 0;
+
+ pevent_register_function(pevent, func, addr, mod);
+ free(func);
+ free(mod);
+
+ line = strtok_r(NULL, "\n", &next);
+ }
+}
+
+void parse_ftrace_printk(char *file, unsigned int size __unused)
+{
+ unsigned long long addr;
+ char *printk;
+ char *line;
+ char *next = NULL;
+ char *addr_str;
+ char *fmt;
+
+ line = strtok_r(file, "\n", &next);
+ while (line) {
+ addr_str = strtok_r(line, ":", &fmt);
+ if (!addr_str) {
+ warning("printk format with empty entry");
+ break;
+ }
+ addr = strtoull(addr_str, NULL, 16);
+ /* fmt still has a space, skip it */
+ printk = strdup(fmt+1);
+ line = strtok_r(NULL, "\n", &next);
+ pevent_register_print_string(pevent, printk, addr);
+ }
+}
+
+int parse_ftrace_file(char *buf, unsigned long size)
+{
+ return pevent_parse_event(pevent, buf, size, "ftrace");
+}
+
+int parse_event_file(char *buf, unsigned long size, char *sys)
+{
+ return pevent_parse_event(pevent, buf, size, sys);
+}
diff --git a/tools/lib/trace/trace-event-read.c b/tools/lib/trace/trace-event-read.c
new file mode 100644
index 0000000..2801b1b
--- /dev/null
+++ b/tools/lib/trace/trace-event-read.c
@@ -0,0 +1,541 @@
+/*
+ * Copyright (C) 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
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#define _FILE_OFFSET_BITS 64
+
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "../../perf/perf.h"
+#include <lk/util.h>
+#include "trace-event.h"
+
+static int input_fd;
+
+static int read_page;
+
+int file_bigendian;
+int host_bigendian;
+static int long_size;
+
+static unsigned long page_size;
+
+static ssize_t calc_data_size;
+static bool repipe;
+
+static int do_read(int fd, void *buf, int size)
+{
+ int rsize = size;
+
+ while (size) {
+ int ret = read(fd, buf, size);
+
+ if (ret <= 0)
+ return -1;
+
+ if (repipe) {
+ int retw = write(STDOUT_FILENO, buf, ret);
+
+ if (retw <= 0 || retw != ret)
+ die("repiping input file");
+ }
+
+ size -= ret;
+ buf += ret;
+ }
+
+ return rsize;
+}
+
+static int read_or_die(void *data, int size)
+{
+ int r;
+
+ r = do_read(input_fd, data, size);
+ if (r <= 0)
+ die("reading input file (size expected=%d received=%d)",
+ size, r);
+
+ if (calc_data_size)
+ calc_data_size += r;
+
+ return r;
+}
+
+/* If it fails, the next read will report it */
+static void skip(int size)
+{
+ char buf[BUFSIZ];
+ int r;
+
+ while (size) {
+ r = size > BUFSIZ ? BUFSIZ : size;
+ read_or_die(buf, r);
+ size -= r;
+ };
+}
+
+static unsigned int read4(void)
+{
+ unsigned int data;
+
+ read_or_die(&data, 4);
+ return __data2host4(perf_pevent, data);
+}
+
+static unsigned long long read8(void)
+{
+ unsigned long long data;
+
+ read_or_die(&data, 8);
+ return __data2host8(perf_pevent, data);
+}
+
+static char *read_string(void)
+{
+ char buf[BUFSIZ];
+ char *str = NULL;
+ int size = 0;
+ off_t r;
+ char c;
+
+ for (;;) {
+ r = read(input_fd, &c, 1);
+ if (r < 0)
+ die("reading input file");
+
+ if (!r)
+ die("no data");
+
+ if (repipe) {
+ int retw = write(STDOUT_FILENO, &c, 1);
+
+ if (retw <= 0 || retw != r)
+ die("repiping input file string");
+ }
+
+ buf[size++] = c;
+
+ if (!c)
+ break;
+ }
+
+ if (calc_data_size)
+ calc_data_size += size;
+
+ str = malloc_or_die(size);
+ memcpy(str, buf, size);
+
+ return str;
+}
+
+static void read_proc_kallsyms(void)
+{
+ unsigned int size;
+ char *buf;
+
+ size = read4();
+ if (!size)
+ return;
+
+ buf = malloc_or_die(size + 1);
+ read_or_die(buf, size);
+ buf[size] = '\0';
+
+ parse_proc_kallsyms(buf, size);
+
+ free(buf);
+}
+
+static void read_ftrace_printk(void)
+{
+ unsigned int size;
+ char *buf;
+
+ size = read4();
+ if (!size)
+ return;
+
+ buf = malloc_or_die(size);
+ read_or_die(buf, size);
+
+ parse_ftrace_printk(buf, size);
+
+ free(buf);
+}
+
+static void read_header_files(void)
+{
+ unsigned long long size;
+ char *header_event;
+ char buf[BUFSIZ];
+
+ read_or_die(buf, 12);
+
+ if (memcmp(buf, "header_page", 12) != 0)
+ die("did not read header page");
+
+ size = read8();
+ skip(size);
+
+ /*
+ * The size field in the page is of type long,
+ * use that instead, since it represents the kernel.
+ */
+ long_size = header_page_size_size;
+
+ read_or_die(buf, 13);
+ if (memcmp(buf, "header_event", 13) != 0)
+ die("did not read header event");
+
+ size = read8();
+ header_event = malloc_or_die(size);
+ read_or_die(header_event, size);
+ free(header_event);
+}
+
+static void read_ftrace_file(unsigned long long size)
+{
+ char *buf;
+
+ buf = malloc_or_die(size);
+ read_or_die(buf, size);
+ parse_ftrace_file(buf, size);
+ free(buf);
+}
+
+static void read_event_file(char *sys, unsigned long long size)
+{
+ char *buf;
+
+ buf = malloc_or_die(size);
+ read_or_die(buf, size);
+ parse_event_file(buf, size, sys);
+ free(buf);
+}
+
+static void read_ftrace_files(void)
+{
+ unsigned long long size;
+ int count;
+ int i;
+
+ count = read4();
+
+ for (i = 0; i < count; i++) {
+ size = read8();
+ read_ftrace_file(size);
+ }
+}
+
+static void read_event_files(void)
+{
+ unsigned long long size;
+ char *sys;
+ int systems;
+ int count;
+ int i,x;
+
+ systems = read4();
+
+ for (i = 0; i < systems; i++) {
+ sys = read_string();
+
+ count = read4();
+ for (x=0; x < count; x++) {
+ size = read8();
+ read_event_file(sys, size);
+ }
+ }
+}
+
+struct cpu_data {
+ unsigned long long offset;
+ unsigned long long size;
+ unsigned long long timestamp;
+ struct record *next;
+ char *page;
+ int cpu;
+ int index;
+ int page_size;
+};
+
+static struct cpu_data *cpu_data;
+
+static void update_cpu_data_index(int cpu)
+{
+ cpu_data[cpu].offset += page_size;
+ cpu_data[cpu].size -= page_size;
+ cpu_data[cpu].index = 0;
+}
+
+static void get_next_page(int cpu)
+{
+ off_t save_seek;
+ off_t ret;
+
+ if (!cpu_data[cpu].page)
+ return;
+
+ if (read_page) {
+ if (cpu_data[cpu].size <= page_size) {
+ free(cpu_data[cpu].page);
+ cpu_data[cpu].page = NULL;
+ return;
+ }
+
+ update_cpu_data_index(cpu);
+
+ /* other parts of the code may expect the pointer to not move */
+ save_seek = lseek(input_fd, 0, SEEK_CUR);
+
+ ret = lseek(input_fd, cpu_data[cpu].offset, SEEK_SET);
+ if (ret == (off_t)-1)
+ die("failed to lseek");
+ ret = read(input_fd, cpu_data[cpu].page, page_size);
+ if (ret < 0)
+ die("failed to read page");
+
+ /* reset the file pointer back */
+ lseek(input_fd, save_seek, SEEK_SET);
+
+ return;
+ }
+
+ munmap(cpu_data[cpu].page, page_size);
+ cpu_data[cpu].page = NULL;
+
+ if (cpu_data[cpu].size <= page_size)
+ return;
+
+ update_cpu_data_index(cpu);
+
+ cpu_data[cpu].page = mmap(NULL, page_size, PROT_READ, MAP_PRIVATE,
+ input_fd, cpu_data[cpu].offset);
+ if (cpu_data[cpu].page == MAP_FAILED)
+ die("failed to mmap cpu %d at offset 0x%llx",
+ cpu, cpu_data[cpu].offset);
+}
+
+static unsigned int type_len4host(unsigned int type_len_ts)
+{
+ if (file_bigendian)
+ return (type_len_ts >> 27) & ((1 << 5) - 1);
+ else
+ return type_len_ts & ((1 << 5) - 1);
+}
+
+static unsigned int ts4host(unsigned int type_len_ts)
+{
+ if (file_bigendian)
+ return type_len_ts & ((1 << 27) - 1);
+ else
+ return type_len_ts >> 5;
+}
+
+static int calc_index(void *ptr, int cpu)
+{
+ return (unsigned long)ptr - (unsigned long)cpu_data[cpu].page;
+}
+
+struct record *trace_peek_data(int cpu)
+{
+ struct record *data;
+ void *page = cpu_data[cpu].page;
+ int idx = cpu_data[cpu].index;
+ void *ptr = page + idx;
+ unsigned long long extend;
+ unsigned int type_len_ts;
+ unsigned int type_len;
+ unsigned int delta;
+ unsigned int length = 0;
+
+ if (cpu_data[cpu].next)
+ return cpu_data[cpu].next;
+
+ if (!page)
+ return NULL;
+
+ if (!idx) {
+ /* FIXME: handle header page */
+ if (header_page_ts_size != 8)
+ die("expected a long long type for timestamp");
+ cpu_data[cpu].timestamp = data2host8(perf_pevent, ptr);
+ ptr += 8;
+ switch (header_page_size_size) {
+ case 4:
+ cpu_data[cpu].page_size = data2host4(perf_pevent, ptr);
+ ptr += 4;
+ break;
+ case 8:
+ cpu_data[cpu].page_size = data2host8(perf_pevent, ptr);
+ ptr += 8;
+ break;
+ default:
+ die("bad long size");
+ }
+ ptr = cpu_data[cpu].page + header_page_data_offset;
+ }
+
+read_again:
+ idx = calc_index(ptr, cpu);
+
+ if (idx >= cpu_data[cpu].page_size) {
+ get_next_page(cpu);
+ return trace_peek_data(cpu);
+ }
+
+ type_len_ts = data2host4(perf_pevent, ptr);
+ ptr += 4;
+
+ type_len = type_len4host(type_len_ts);
+ delta = ts4host(type_len_ts);
+
+ switch (type_len) {
+ case RINGBUF_TYPE_PADDING:
+ if (!delta)
+ die("error, hit unexpected end of page");
+ length = data2host4(perf_pevent, ptr);
+ ptr += 4;
+ length *= 4;
+ ptr += length;
+ goto read_again;
+
+ case RINGBUF_TYPE_TIME_EXTEND:
+ extend = data2host4(perf_pevent, ptr);
+ ptr += 4;
+ extend <<= TS_SHIFT;
+ extend += delta;
+ cpu_data[cpu].timestamp += extend;
+ goto read_again;
+
+ case RINGBUF_TYPE_TIME_STAMP:
+ ptr += 12;
+ break;
+ case 0:
+ length = data2host4(perf_pevent, ptr);
+ ptr += 4;
+ die("here! length=%d", length);
+ break;
+ default:
+ length = type_len * 4;
+ break;
+ }
+
+ cpu_data[cpu].timestamp += delta;
+
+ data = malloc_or_die(sizeof(*data));
+ memset(data, 0, sizeof(*data));
+
+ data->ts = cpu_data[cpu].timestamp;
+ data->size = length;
+ data->data = ptr;
+ ptr += length;
+
+ cpu_data[cpu].index = calc_index(ptr, cpu);
+ cpu_data[cpu].next = data;
+
+ return data;
+}
+
+struct record *trace_read_data(int cpu)
+{
+ struct record *data;
+
+ data = trace_peek_data(cpu);
+ cpu_data[cpu].next = NULL;
+
+ return data;
+}
+
+ssize_t trace_report(int fd, bool __repipe)
+{
+ char buf[BUFSIZ];
+ char test[] = { 23, 8, 68 };
+ char *version;
+ int show_version = 0;
+ int show_funcs = 0;
+ int show_printk = 0;
+ ssize_t size;
+
+ calc_data_size = 1;
+ repipe = __repipe;
+
+ input_fd = fd;
+
+ read_or_die(buf, 3);
+ if (memcmp(buf, test, 3) != 0)
+ die("no trace data in the file");
+
+ read_or_die(buf, 7);
+ if (memcmp(buf, "tracing", 7) != 0)
+ die("not a trace file (missing 'tracing' tag)");
+
+ version = read_string();
+ if (show_version)
+ printf("version = %s\n", version);
+ free(version);
+
+ read_or_die(buf, 1);
+ file_bigendian = buf[0];
+ host_bigendian = bigendian();
+
+ read_trace_init(file_bigendian, host_bigendian);
+
+ read_or_die(buf, 1);
+ long_size = buf[0];
+
+ page_size = read4();
+
+ read_header_files();
+
+ read_ftrace_files();
+ read_event_files();
+ read_proc_kallsyms();
+ read_ftrace_printk();
+
+ size = calc_data_size - 1;
+ calc_data_size = 0;
+ repipe = false;
+
+ if (show_funcs) {
+ pevent_print_funcs(perf_pevent);
+ return size;
+ }
+ if (show_printk) {
+ pevent_print_printk(perf_pevent);
+ return size;
+ }
+
+ return size;
+}
diff --git a/tools/lib/trace/trace-event.h b/tools/lib/trace/trace-event.h
new file mode 100644
index 0000000..9c9d342
--- /dev/null
+++ b/tools/lib/trace/trace-event.h
@@ -0,0 +1,115 @@
+#ifndef _PERF_UTIL_TRACE_EVENT_H
+#define _PERF_UTIL_TRACE_EVENT_H
+
+#include "../../perf/perf.h"
+#include "parse-events.h"
+
+extern int header_page_size_size;
+extern int header_page_ts_size;
+extern int header_page_data_offset;
+
+extern bool latency_format;
+extern struct pevent *perf_pevent;
+
+struct scripting_context {
+ void *event_data;
+};
+
+enum {
+ RINGBUF_TYPE_PADDING = 29,
+ RINGBUF_TYPE_TIME_EXTEND = 30,
+ RINGBUF_TYPE_TIME_STAMP = 31,
+};
+
+#ifndef TS_SHIFT
+#define TS_SHIFT 27
+#endif
+
+int bigendian(void);
+
+int read_trace_init(int file_bigendian, int host_bigendian);
+
+void print_event(int cpu, void *data, int size, unsigned long long nsecs,
+ char *comm);
+
+struct record *trace_read_data(int cpu);
+int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events);
+ssize_t read_tracing_data_size(int fd, struct perf_event_attr *pattrs,
+ int nb_events);
+
+int parse_ftrace_file(char *buf, unsigned long size);
+int parse_event_file(char *buf, unsigned long size, char *sys);
+
+struct record *trace_peek_data(int cpu);
+struct event_format *trace_find_event(int type);
+
+unsigned long long
+raw_field_value(struct event_format *event, const char *name, void *data);
+void *raw_field_ptr(struct event_format *event, const char *name, void *data);
+
+void parse_proc_kallsyms(char *file, unsigned int size __unused);
+void parse_ftrace_printk(char *file, unsigned int size __unused);
+
+ssize_t trace_report(int fd, bool repipe);
+
+struct scripting_ops {
+ const char *name;
+ int (*start_script) (const char *script, int argc, const char **argv);
+ int (*stop_script) (void);
+ void (*process_event) (int cpu, void *data, int size,
+ unsigned long long nsecs, char *comm);
+ int (*generate_script) (const char *outfile);
+};
+
+int script_spec_register(const char *spec, struct scripting_ops *ops);
+
+void setup_perl_scripting(void);
+void setup_python_scripting(void);
+
+int trace_parse_common_type(void *data);
+int trace_parse_common_pid(void *data);
+#if 0
+int parse_common_pc(void *data);
+int parse_common_flags(void *data);
+int parse_common_lock_depth(void *data);
+struct event_format *trace_find_event(int id);
+#endif
+struct event_format *trace_find_next_event(struct event_format *event);
+unsigned long long read_size(void *ptr, int size);
+#if 0
+unsigned long long
+raw_field_value(struct event_format *event, const char *name, void *data);
+void *raw_field_ptr(struct event_format *event, const char *name, void *data);
+#endif
+unsigned long long eval_flag(const char *flag);
+
+int common_pc(struct scripting_context *context);
+int common_flags(struct scripting_context *context);
+int common_lock_depth(struct scripting_context *context);
+
+#define MAX_EVENT_LENGTH 512
+#define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1)
+
+#define for_each_subsystem(sys_dir, sys_dirent, sys_next) \
+ while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \
+ if (sys_dirent.d_type == DT_DIR && \
+ (strcmp(sys_dirent.d_name, ".")) && \
+ (strcmp(sys_dirent.d_name, "..")))
+
+#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \
+ while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \
+ if (evt_dirent.d_type == DT_DIR && \
+ (strcmp(evt_dirent.d_name, ".")) && \
+ (strcmp(evt_dirent.d_name, "..")) && \
+ (!tp_event_has_id(&sys_dirent, &evt_dirent)))
+
+
+struct tracepoint_path {
+ char *system;
+ char *name;
+ struct tracepoint_path *next;
+};
+
+extern int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir);
+extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
+#endif /* _PERF_UTIL_TRACE_EVENT_H */
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 98cdd20..f899b08 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -370,7 +370,6 @@ LIB_H += util/values.h
LIB_H += util/sort.h
LIB_H += util/hist.h
LIB_H += util/thread.h
-LIB_H += util/trace-event.h
LIB_H += util/probe-finder.h
LIB_H += util/probe-event.h
LIB_H += util/pstack.h
@@ -399,9 +398,6 @@ LIB_OBJS += $(OUTPUT)util/debug.o
LIB_OBJS += $(OUTPUT)util/pstack.o
LIB_OBJS += $(OUTPUT)util/session.o
LIB_OBJS += $(OUTPUT)util/thread.o
-LIB_OBJS += $(OUTPUT)util/trace-event-parse.o
-LIB_OBJS += $(OUTPUT)util/trace-event-read.o
-LIB_OBJS += $(OUTPUT)util/trace-event-info.o
LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o
LIB_OBJS += $(OUTPUT)util/svghelper.o
LIB_OBJS += $(OUTPUT)util/sort.o
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 703cc93..e432afe 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -9,7 +9,7 @@
#include "util/session.h"

#include "util/parse-options.h"
-#include "util/trace-event.h"
+#include <trace/trace-event.h>

#include "util/debug.h"

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index b849f99e..75ef557 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -9,7 +9,7 @@
#include "util/session.h"

#include "util/parse-options.h"
-#include "util/trace-event.h"
+#include <trace/trace-event.h>

#include "util/debug.h"

diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 6257d26..94b454f 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -8,7 +8,7 @@
#include "util/header.h"

#include "util/parse-options.h"
-#include "util/trace-event.h"
+#include <trace/trace-event.h>

#include "util/debug.h"
#include "util/session.h"
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index c881900..4ef6fe1 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -9,7 +9,7 @@
#include "util/session.h"

#include "util/parse-options.h"
-#include "util/trace-event.h"
+#include <trace/trace-event.h>

#include "util/debug.h"

diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 43cfc18..2b010ec 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -314,25 +314,6 @@ struct wakeup_entry {
int success;
};

-/*
- * trace_flag_type is an enumeration that holds different
- * states when a trace occurs. These are:
- * IRQS_OFF - interrupts were disabled
- * IRQS_NOSUPPORT - arch does not support irqs_disabled_flags
- * NEED_RESCED - reschedule is requested
- * HARDIRQ - inside an interrupt handler
- * SOFTIRQ - inside a softirq handler
- */
-enum trace_flag_type {
- TRACE_FLAG_IRQS_OFF = 0x01,
- TRACE_FLAG_IRQS_NOSUPPORT = 0x02,
- TRACE_FLAG_NEED_RESCHED = 0x04,
- TRACE_FLAG_HARDIRQ = 0x08,
- TRACE_FLAG_SOFTIRQ = 0x10,
-};
-
-
-
struct sched_switch {
struct trace_entry te;
char prev_comm[TASK_COMM_LEN];
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index a6c41c6..f41a9e0 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -9,7 +9,7 @@
#include "util/session.h"
#include <perf/config.h>
#include "util/thread.h"
-#include "util/trace-event.h"
+#include <trace/trace-event.h>
#include <lk/util.h>

static char const *script_name;
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.c b/tools/perf/scripts/perl/Perf-Trace-Util/Context.c
index 01a64ad..f38aacf 100644
--- a/tools/perf/scripts/perl/Perf-Trace-Util/Context.c
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/Context.c
@@ -32,7 +32,7 @@
#include "perl.h"
#include "XSUB.h"
#include "../../../perf.h"
-#include "../../../util/trace-event.h"
+#include <trace/trace-event.h>

#ifndef PERL_UNUSED_VAR
# define PERL_UNUSED_VAR(var) if (0) var = var
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs b/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
index 549cf04..baff89f 100644
--- a/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
@@ -23,7 +23,7 @@
#include "perl.h"
#include "XSUB.h"
#include "../../../perf.h"
-#include "../../../util/trace-event.h"
+#include <trace/trace-event.h>

MODULE = Perf::Trace::Context PACKAGE = Perf::Trace::Context
PROTOTYPES: ENABLE
diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Context.c b/tools/perf/scripts/python/Perf-Trace-Util/Context.c
index 957085d..6474be7 100644
--- a/tools/perf/scripts/python/Perf-Trace-Util/Context.c
+++ b/tools/perf/scripts/python/Perf-Trace-Util/Context.c
@@ -21,7 +21,7 @@

#include <Python.h>
#include "../../../perf.h"
-#include "../../../util/trace-event.h"
+#include <trace/trace-event.h>

PyMODINIT_FUNC initperf_trace_context(void);

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index f233545..e0f84b5 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -6,15 +6,16 @@
#include <stdio.h>
#include <stdlib.h>
#include <linux/list.h>
+#include <lk/util.h>
#include <lk/kernel.h>
+#include <perf/symbol.h>
+#include <trace/trace-event.h>

-#include <lk/util.h>
#include "header.h"
#include "../perf.h"
-#include "trace-event.h"
#include "session.h"
-#include <perf/symbol.h>
#include "debug.h"
+#include "parse-events.h"

static bool no_buildid_cache = false;

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index ad36237..6e1e01c 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -8,6 +8,7 @@
#include "exec_cmd.h"
#include "string.h"
#include <perf/symbol.h>
+#include <trace/trace-event.h>
#include "cache.h"
#include "header.h"

@@ -29,8 +30,6 @@ enum event_result {
EVT_HANDLED_ALL
};

-char debugfs_path[MAXPATHLEN];
-
#define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x
#define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x

@@ -126,106 +125,6 @@ static unsigned long hw_cache_stat[C(MAX)] = {
[C(BPU)] = (CACHE_READ),
};

-#define for_each_subsystem(sys_dir, sys_dirent, sys_next) \
- while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \
- if (sys_dirent.d_type == DT_DIR && \
- (strcmp(sys_dirent.d_name, ".")) && \
- (strcmp(sys_dirent.d_name, "..")))
-
-static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
-{
- char evt_path[MAXPATHLEN];
- int fd;
-
- snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path,
- sys_dir->d_name, evt_dir->d_name);
- fd = open(evt_path, O_RDONLY);
- if (fd < 0)
- return -EINVAL;
- close(fd);
-
- return 0;
-}
-
-#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) \
- while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \
- if (evt_dirent.d_type == DT_DIR && \
- (strcmp(evt_dirent.d_name, ".")) && \
- (strcmp(evt_dirent.d_name, "..")) && \
- (!tp_event_has_id(&sys_dirent, &evt_dirent)))
-
-#define MAX_EVENT_LENGTH 512
-
-
-struct tracepoint_path *tracepoint_id_to_path(u64 config)
-{
- struct tracepoint_path *path = NULL;
- DIR *sys_dir, *evt_dir;
- struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
- char id_buf[4];
- int fd;
- u64 id;
- char evt_path[MAXPATHLEN];
- char dir_path[MAXPATHLEN];
-
- if (debugfs_valid_mountpoint(debugfs_path))
- return NULL;
-
- sys_dir = opendir(debugfs_path);
- if (!sys_dir)
- return NULL;
-
- for_each_subsystem(sys_dir, sys_dirent, sys_next) {
-
- snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
- sys_dirent.d_name);
- evt_dir = opendir(dir_path);
- if (!evt_dir)
- continue;
-
- for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
-
- snprintf(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) {
- closedir(evt_dir);
- closedir(sys_dir);
- path = zalloc(sizeof(*path));
- path->system = malloc(MAX_EVENT_LENGTH);
- if (!path->system) {
- free(path);
- return NULL;
- }
- path->name = malloc(MAX_EVENT_LENGTH);
- if (!path->name) {
- free(path->system);
- free(path);
- return NULL;
- }
- strncpy(path->system, sys_dirent.d_name,
- MAX_EVENT_LENGTH);
- strncpy(path->name, evt_dirent.d_name,
- MAX_EVENT_LENGTH);
- return path;
- }
- }
- closedir(evt_dir);
- }
-
- closedir(sys_dir);
- return NULL;
-}
-
-#define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1)
static const char *tracepoint_id_to_name(u64 config)
{
static char buf[TP_PATH_LEN];
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 9492e3c..41ebdc4 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -4,16 +4,10 @@
* Parse symbolic events/counts passed in as options:
*/
#include <perf/util.h>
+#include <trace/parse-events.h>

struct option;

-struct tracepoint_path {
- char *system;
- char *name;
- struct tracepoint_path *next;
-};
-
-extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
extern bool have_tracepoints(struct perf_event_attr *pattrs, int nb_events);

extern int nr_counters;
@@ -31,7 +25,6 @@ extern int parse_filter(const struct option *opt, const char *str, int unset);

extern void print_events(void);

-extern char debugfs_path[];
extern int valid_debugfs_mount(const char *debugfs);

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 577944c..2bed689 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -44,7 +44,7 @@
#include <perf/color.h>
#include <perf/symbol.h>
#include "thread.h"
-#include "trace-event.h" /* For __unused */
+#include <trace/trace-event.h> /* For __unused */
#include "probe-event.h"
#include "probe-finder.h"

diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index 78af7d1..af37491 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -27,7 +27,7 @@

#include "../../perf.h"
#include <lk/util.h>
-#include "../trace-event.h"
+#include <trace/trace-event.h>

#include <EXTERN.h>
#include <perl.h>
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 524d355..464c25a 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -29,7 +29,7 @@

#include "../../perf.h"
#include <lk/util.h>
-#include "../trace-event.h"
+#include <trace/trace-event.h>

PyMODINIT_FUNC initperf_trace_context(void);

diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
deleted file mode 100644
index fadc2c0..0000000
--- a/tools/perf/util/trace-event-info.c
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- * 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
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-#define _GNU_SOURCE
-#include <dirent.h>
-#include <mntent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <pthread.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <lk/kernel.h>
-
-#include <lk/debugfs.h>
-
-#include "../perf.h"
-#include "trace-event.h"
-
-#define VERSION "0.5"
-
-#define _STR(x) #x
-#define STR(x) _STR(x)
-#define MAX_PATH 256
-
-#define TRACE_CTRL "tracing_on"
-#define TRACE "trace"
-#define AVAILABLE "available_tracers"
-#define CURRENT "current_tracer"
-#define ITER_CTRL "trace_options"
-#define MAX_LATENCY "tracing_max_latency"
-
-unsigned int page_size;
-
-static const char *output_file = "trace.info";
-static int output_fd;
-
-struct event_list {
- struct event_list *next;
- const char *event;
-};
-
-struct events {
- struct events *sibling;
- struct events *children;
- struct events *next;
- char *name;
-};
-
-
-
-static void die(const char *fmt, ...)
-{
- va_list ap;
- int ret = errno;
-
- if (errno)
- perror("trace-cmd");
- else
- ret = -1;
-
- va_start(ap, fmt);
- fprintf(stderr, " ");
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-
- fprintf(stderr, "\n");
- exit(ret);
-}
-
-void *malloc_or_die(unsigned int size)
-{
- void *data;
-
- data = malloc(size);
- if (!data)
- die("malloc");
- return data;
-}
-
-static const char *find_debugfs(void)
-{
- const char *path = debugfs_mount(NULL);
-
- if (!path)
- die("Your kernel not support debugfs filesystem");
-
- return path;
-}
-
-/*
- * Finds the path to the debugfs/tracing
- * Allocates the string and stores it.
- */
-static const char *find_tracing_dir(void)
-{
- static char *tracing;
- static int tracing_found;
- const char *debugfs;
-
- if (tracing_found)
- return tracing;
-
- debugfs = find_debugfs();
-
- tracing = malloc_or_die(strlen(debugfs) + 9);
-
- sprintf(tracing, "%s/tracing", debugfs);
-
- tracing_found = 1;
- return tracing;
-}
-
-static char *get_tracing_file(const char *name)
-{
- const char *tracing;
- char *file;
-
- tracing = find_tracing_dir();
- if (!tracing)
- return NULL;
-
- file = malloc_or_die(strlen(tracing) + strlen(name) + 2);
-
- sprintf(file, "%s/%s", tracing, name);
- return file;
-}
-
-static void put_tracing_file(char *file)
-{
- free(file);
-}
-
-static ssize_t calc_data_size;
-
-static ssize_t write_or_die(const void *buf, size_t len)
-{
- int ret;
-
- if (calc_data_size) {
- calc_data_size += len;
- return len;
- }
-
- ret = write(output_fd, buf, len);
- if (ret < 0)
- die("writing to '%s'", output_file);
-
- return ret;
-}
-
-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;
-}
-
-static unsigned long long copy_file_fd(int fd)
-{
- unsigned long long size = 0;
- char buf[BUFSIZ];
- int r;
-
- do {
- r = read(fd, buf, BUFSIZ);
- if (r > 0) {
- size += r;
- write_or_die(buf, r);
- }
- } while (r > 0);
-
- return size;
-}
-
-static unsigned long long copy_file(const char *file)
-{
- unsigned long long size = 0;
- int fd;
-
- fd = open(file, O_RDONLY);
- if (fd < 0)
- die("Can't read '%s'", file);
- size = copy_file_fd(fd);
- close(fd);
-
- return size;
-}
-
-static unsigned long get_size_fd(int fd)
-{
- unsigned long long size = 0;
- char buf[BUFSIZ];
- int r;
-
- do {
- r = read(fd, buf, BUFSIZ);
- if (r > 0)
- size += r;
- } while (r > 0);
-
- lseek(fd, 0, SEEK_SET);
-
- return size;
-}
-
-static unsigned long get_size(const char *file)
-{
- unsigned long long size = 0;
- int fd;
-
- fd = open(file, O_RDONLY);
- if (fd < 0)
- die("Can't read '%s'", file);
- size = get_size_fd(fd);
- close(fd);
-
- return size;
-}
-
-static void read_header_files(void)
-{
- unsigned long long size, check_size;
- char *path;
- int fd;
-
- path = get_tracing_file("events/header_page");
- fd = open(path, O_RDONLY);
- if (fd < 0)
- die("can't read '%s'", path);
-
- /* unfortunately, you can not stat debugfs files for size */
- size = get_size_fd(fd);
-
- write_or_die("header_page", 12);
- write_or_die(&size, 8);
- check_size = copy_file_fd(fd);
- close(fd);
-
- if (size != check_size)
- die("wrong size for '%s' size=%lld read=%lld",
- path, size, check_size);
- put_tracing_file(path);
-
- path = get_tracing_file("events/header_event");
- fd = open(path, O_RDONLY);
- if (fd < 0)
- die("can't read '%s'", path);
-
- size = get_size_fd(fd);
-
- write_or_die("header_event", 13);
- write_or_die(&size, 8);
- check_size = copy_file_fd(fd);
- if (size != check_size)
- die("wrong size for '%s'", path);
- put_tracing_file(path);
- close(fd);
-}
-
-static bool name_in_tp_list(char *sys, struct tracepoint_path *tps)
-{
- while (tps) {
- if (!strcmp(sys, tps->name))
- return true;
- tps = tps->next;
- }
-
- return false;
-}
-
-static void copy_event_system(const char *sys, struct tracepoint_path *tps)
-{
- unsigned long long size, check_size;
- struct dirent *dent;
- struct stat st;
- char *format;
- DIR *dir;
- int count = 0;
- int ret;
-
- dir = opendir(sys);
- if (!dir)
- die("can't read directory '%s'", sys);
-
- while ((dent = readdir(dir))) {
- if (dent->d_type != DT_DIR ||
- strcmp(dent->d_name, ".") == 0 ||
- strcmp(dent->d_name, "..") == 0 ||
- !name_in_tp_list(dent->d_name, tps))
- continue;
- format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10);
- sprintf(format, "%s/%s/format", sys, dent->d_name);
- ret = stat(format, &st);
- free(format);
- if (ret < 0)
- continue;
- count++;
- }
-
- write_or_die(&count, 4);
-
- rewinddir(dir);
- while ((dent = readdir(dir))) {
- if (dent->d_type != DT_DIR ||
- strcmp(dent->d_name, ".") == 0 ||
- strcmp(dent->d_name, "..") == 0 ||
- !name_in_tp_list(dent->d_name, tps))
- continue;
- format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10);
- sprintf(format, "%s/%s/format", sys, dent->d_name);
- ret = stat(format, &st);
-
- if (ret >= 0) {
- /* unfortunately, you can not stat debugfs files for size */
- size = get_size(format);
- write_or_die(&size, 8);
- check_size = copy_file(format);
- if (size != check_size)
- die("error in size of file '%s'", format);
- }
-
- free(format);
- }
- closedir(dir);
-}
-
-static void read_ftrace_files(struct tracepoint_path *tps)
-{
- char *path;
-
- path = get_tracing_file("events/ftrace");
-
- copy_event_system(path, tps);
-
- put_tracing_file(path);
-}
-
-static bool system_in_tp_list(char *sys, struct tracepoint_path *tps)
-{
- while (tps) {
- if (!strcmp(sys, tps->system))
- return true;
- tps = tps->next;
- }
-
- return false;
-}
-
-static void read_event_files(struct tracepoint_path *tps)
-{
- struct dirent *dent;
- struct stat st;
- char *path;
- char *sys;
- DIR *dir;
- int count = 0;
- int ret;
-
- path = get_tracing_file("events");
-
- dir = opendir(path);
- if (!dir)
- die("can't read directory '%s'", path);
-
- while ((dent = readdir(dir))) {
- if (dent->d_type != DT_DIR ||
- strcmp(dent->d_name, ".") == 0 ||
- strcmp(dent->d_name, "..") == 0 ||
- strcmp(dent->d_name, "ftrace") == 0 ||
- !system_in_tp_list(dent->d_name, tps))
- continue;
- count++;
- }
-
- write_or_die(&count, 4);
-
- rewinddir(dir);
- while ((dent = readdir(dir))) {
- if (dent->d_type != DT_DIR ||
- strcmp(dent->d_name, ".") == 0 ||
- strcmp(dent->d_name, "..") == 0 ||
- strcmp(dent->d_name, "ftrace") == 0 ||
- !system_in_tp_list(dent->d_name, tps))
- continue;
- sys = malloc_or_die(strlen(path) + strlen(dent->d_name) + 2);
- sprintf(sys, "%s/%s", path, dent->d_name);
- ret = stat(sys, &st);
- if (ret >= 0) {
- write_or_die(dent->d_name, strlen(dent->d_name) + 1);
- copy_event_system(sys, tps);
- }
- free(sys);
- }
-
- closedir(dir);
- put_tracing_file(path);
-}
-
-static void read_proc_kallsyms(void)
-{
- unsigned int size, check_size;
- const char *path = "/proc/kallsyms";
- struct stat st;
- int ret;
-
- ret = stat(path, &st);
- if (ret < 0) {
- /* not found */
- size = 0;
- write_or_die(&size, 4);
- return;
- }
- size = get_size(path);
- write_or_die(&size, 4);
- check_size = copy_file(path);
- if (size != check_size)
- die("error in size of file '%s'", path);
-
-}
-
-static void read_ftrace_printk(void)
-{
- unsigned int size, check_size;
- char *path;
- struct stat st;
- int ret;
-
- path = get_tracing_file("printk_formats");
- ret = stat(path, &st);
- if (ret < 0) {
- /* not found */
- size = 0;
- write_or_die(&size, 4);
- goto out;
- }
- size = get_size(path);
- write_or_die(&size, 4);
- check_size = copy_file(path);
- if (size != check_size)
- die("error in size of file '%s'", path);
-out:
- put_tracing_file(path);
-}
-
-static struct tracepoint_path *
-get_tracepoints_path(struct perf_event_attr *pattrs, int nb_events)
-{
- struct tracepoint_path path, *ppath = &path;
- int i, nr_tracepoints = 0;
-
- for (i = 0; i < nb_events; i++) {
- if (pattrs[i].type != PERF_TYPE_TRACEPOINT)
- continue;
- ++nr_tracepoints;
- ppath->next = tracepoint_id_to_path(pattrs[i].config);
- if (!ppath->next)
- die("%s\n", "No memory to alloc tracepoints list");
- ppath = ppath->next;
- }
-
- return nr_tracepoints > 0 ? path.next : NULL;
-}
-
-bool have_tracepoints(struct perf_event_attr *pattrs, int nb_events)
-{
- int i;
-
- for (i = 0; i < nb_events; i++)
- if (pattrs[i].type == PERF_TYPE_TRACEPOINT)
- return true;
-
- return false;
-}
-
-int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events)
-{
- char buf[BUFSIZ];
- struct tracepoint_path *tps = get_tracepoints_path(pattrs, nb_events);
-
- /*
- * What? No tracepoints? No sense writing anything here, bail out.
- */
- if (tps == NULL)
- return -1;
-
- output_fd = fd;
-
- buf[0] = 23;
- buf[1] = 8;
- buf[2] = 68;
- memcpy(buf + 3, "tracing", 7);
-
- write_or_die(buf, 10);
-
- write_or_die(VERSION, strlen(VERSION) + 1);
-
- /* save endian */
- if (bigendian())
- buf[0] = 1;
- else
- buf[0] = 0;
-
- read_trace_init(buf[0], buf[0]);
-
- write_or_die(buf, 1);
-
- /* save size of long */
- buf[0] = sizeof(long);
- write_or_die(buf, 1);
-
- /* save page_size */
- page_size = sysconf(_SC_PAGESIZE);
- write_or_die(&page_size, 4);
-
- read_header_files();
- read_ftrace_files(tps);
- read_event_files(tps);
- read_proc_kallsyms();
- read_ftrace_printk();
-
- return 0;
-}
-
-ssize_t read_tracing_data_size(int fd, struct perf_event_attr *pattrs,
- int nb_events)
-{
- ssize_t size;
- int err = 0;
-
- calc_data_size = 1;
- err = read_tracing_data(fd, pattrs, nb_events);
- size = calc_data_size - 1;
- calc_data_size = 0;
-
- if (err < 0)
- return err;
-
- return size;
-}
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
deleted file mode 100644
index 489907c..0000000
--- a/tools/perf/util/trace-event-parse.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 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
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#undef _GNU_SOURCE
-#include "../perf.h"
-#include <lk/util.h>
-#include "trace-event.h"
-
-int header_page_size_size;
-int header_page_ts_size;
-int header_page_data_offset;
-
-struct pevent *perf_pevent;
-static struct pevent *pevent;
-
-bool latency_format;
-
-int read_trace_init(int file_bigendian, int host_bigendian)
-{
- if (pevent)
- return 0;
-
- perf_pevent = pevent_alloc();
- pevent = perf_pevent;
-
- pevent_set_file_bigendian(pevent, file_bigendian);
- pevent_set_host_bigendian(pevent, host_bigendian);
-
- return 0;
-}
-
-unsigned long long
-raw_field_value(struct event_format *event, const char *name, void *data)
-{
- struct format_field *field;
- unsigned long long val;
-
- field = pevent_find_any_field(event, name);
- if (!field)
- return 0ULL;
-
- pevent_read_number_field(field, data, &val);
-
- return val;
-}
-
-void *raw_field_ptr(struct event_format *event, const char *name, void *data)
-{
- struct format_field *field;
-
- field = pevent_find_any_field(event, name);
- if (!field)
- return NULL;
-
- if (field->flags & FIELD_IS_DYNAMIC) {
- int offset;
-
- offset = *(int *)(data + field->offset);
- offset &= 0xffff;
-
- return data + offset;
- }
-
- return data + field->offset;
-}
-
-int trace_parse_common_type(void *data)
-{
- struct record record;
-
- record.data = data;
- return pevent_data_type(pevent, &record);
-}
-
-struct event_format *trace_find_event(int type)
-{
- return pevent_find_event(pevent, type);
-}
-
-void print_event(int cpu, void *data, int size, unsigned long long nsecs,
- char *comm)
-{
- struct record record;
- struct trace_seq s;
- int pid;
-
- pevent->latency_format = latency_format;
-
- record.ts = nsecs;
- record.cpu = cpu;
- record.size = size;
- record.data = data;
- pid = pevent_data_pid(pevent, &record);
-
- if (!pevent_pid_is_registered(pevent, pid))
- pevent_register_comm(pevent, comm, pid);
-
- trace_seq_init(&s);
- pevent_print_event(pevent, &s, &record);
- trace_seq_do_printf(&s);
- printf("\n");
-
-#if 0
- struct event *event;
- unsigned long secs;
- unsigned long usecs;
- int type;
- int pid;
-
- secs = nsecs / NSECS_PER_SEC;
- nsecs -= secs * NSECS_PER_SEC;
- usecs = nsecs / NSECS_PER_USEC;
-
- type = trace_parse_common_type(data);
-
- event = trace_find_event(type);
- if (!event) {
- warning("ug! no event found for type %d", type);
- return;
- }
-
- pid = trace_parse_common_pid(data);
-
- if (latency_format) {
- printf("%8.8s-%-5d %3d",
- comm, pid, cpu);
- print_lat_fmt(data, size);
- } else
- printf("%16s-%-5d [%03d]", comm, pid, cpu);
-
- printf(" %5lu.%06lu: %s: ", secs, usecs, event->name);
-
- if (event->flags & EVENT_FL_FAILED) {
- printf("EVENT '%s' FAILED TO PARSE\n",
- event->name);
- return;
- }
-
- pretty_print(data, size, event);
- printf("\n");
-#endif
-}
-
-void parse_proc_kallsyms(char *file, unsigned int size __unused)
-{
- unsigned long long addr;
- char *func;
- char *line;
- char *next = NULL;
- char *addr_str;
- char *mod;
- char ch;
- int ret;
-
- line = strtok_r(file, "\n", &next);
- while (line) {
- mod = NULL;
- ret = sscanf(line, "%as %c %as\t[%as",
- (float *)(void *)&addr_str, /* workaround gcc warning */
- &ch,
- (float *)(void *)&func,
- (float *)(void *)&mod);
- addr = strtoull(addr_str, NULL, 16);
- free(addr_str);
-
- /* truncate the extra ']' */
- if (mod)
- mod[strlen(mod) - 1] = 0;
-
- pevent_register_function(pevent, func, addr, mod);
- free(func);
- free(mod);
-
- line = strtok_r(NULL, "\n", &next);
- }
-}
-
-void parse_ftrace_printk(char *file, unsigned int size __unused)
-{
- unsigned long long addr;
- char *printk;
- char *line;
- char *next = NULL;
- char *addr_str;
- char *fmt;
-
- line = strtok_r(file, "\n", &next);
- while (line) {
- addr_str = strtok_r(line, ":", &fmt);
- if (!addr_str) {
- warning("printk format with empty entry");
- break;
- }
- addr = strtoull(addr_str, NULL, 16);
- /* fmt still has a space, skip it */
- printk = strdup(fmt+1);
- line = strtok_r(NULL, "\n", &next);
- pevent_register_print_string(pevent, printk, addr);
- }
-}
-
-int parse_ftrace_file(char *buf, unsigned long size)
-{
- return pevent_parse_event(pevent, buf, size, "ftrace");
-}
-
-int parse_event_file(char *buf, unsigned long size, char *sys)
-{
- return pevent_parse_event(pevent, buf, size, sys);
-}
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
deleted file mode 100644
index d42a5a9..0000000
--- a/tools/perf/util/trace-event-read.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * Copyright (C) 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
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-#define _FILE_OFFSET_BITS 64
-
-#include <dirent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <pthread.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include "../perf.h"
-#include <lk/util.h>
-#include "trace-event.h"
-
-static int input_fd;
-
-static int read_page;
-
-int file_bigendian;
-int host_bigendian;
-static int long_size;
-
-static unsigned long page_size;
-
-static ssize_t calc_data_size;
-static bool repipe;
-
-static int do_read(int fd, void *buf, int size)
-{
- int rsize = size;
-
- while (size) {
- int ret = read(fd, buf, size);
-
- if (ret <= 0)
- return -1;
-
- if (repipe) {
- int retw = write(STDOUT_FILENO, buf, ret);
-
- if (retw <= 0 || retw != ret)
- die("repiping input file");
- }
-
- size -= ret;
- buf += ret;
- }
-
- return rsize;
-}
-
-static int read_or_die(void *data, int size)
-{
- int r;
-
- r = do_read(input_fd, data, size);
- if (r <= 0)
- die("reading input file (size expected=%d received=%d)",
- size, r);
-
- if (calc_data_size)
- calc_data_size += r;
-
- return r;
-}
-
-/* If it fails, the next read will report it */
-static void skip(int size)
-{
- char buf[BUFSIZ];
- int r;
-
- while (size) {
- r = size > BUFSIZ ? BUFSIZ : size;
- read_or_die(buf, r);
- size -= r;
- };
-}
-
-static unsigned int read4(void)
-{
- unsigned int data;
-
- read_or_die(&data, 4);
- return __data2host4(perf_pevent, data);
-}
-
-static unsigned long long read8(void)
-{
- unsigned long long data;
-
- read_or_die(&data, 8);
- return __data2host8(perf_pevent, data);
-}
-
-static char *read_string(void)
-{
- char buf[BUFSIZ];
- char *str = NULL;
- int size = 0;
- off_t r;
- char c;
-
- for (;;) {
- r = read(input_fd, &c, 1);
- if (r < 0)
- die("reading input file");
-
- if (!r)
- die("no data");
-
- if (repipe) {
- int retw = write(STDOUT_FILENO, &c, 1);
-
- if (retw <= 0 || retw != r)
- die("repiping input file string");
- }
-
- buf[size++] = c;
-
- if (!c)
- break;
- }
-
- if (calc_data_size)
- calc_data_size += size;
-
- str = malloc_or_die(size);
- memcpy(str, buf, size);
-
- return str;
-}
-
-static void read_proc_kallsyms(void)
-{
- unsigned int size;
- char *buf;
-
- size = read4();
- if (!size)
- return;
-
- buf = malloc_or_die(size + 1);
- read_or_die(buf, size);
- buf[size] = '\0';
-
- parse_proc_kallsyms(buf, size);
-
- free(buf);
-}
-
-static void read_ftrace_printk(void)
-{
- unsigned int size;
- char *buf;
-
- size = read4();
- if (!size)
- return;
-
- buf = malloc_or_die(size);
- read_or_die(buf, size);
-
- parse_ftrace_printk(buf, size);
-
- free(buf);
-}
-
-static void read_header_files(void)
-{
- unsigned long long size;
- char *header_event;
- char buf[BUFSIZ];
-
- read_or_die(buf, 12);
-
- if (memcmp(buf, "header_page", 12) != 0)
- die("did not read header page");
-
- size = read8();
- skip(size);
-
- /*
- * The size field in the page is of type long,
- * use that instead, since it represents the kernel.
- */
- long_size = header_page_size_size;
-
- read_or_die(buf, 13);
- if (memcmp(buf, "header_event", 13) != 0)
- die("did not read header event");
-
- size = read8();
- header_event = malloc_or_die(size);
- read_or_die(header_event, size);
- free(header_event);
-}
-
-static void read_ftrace_file(unsigned long long size)
-{
- char *buf;
-
- buf = malloc_or_die(size);
- read_or_die(buf, size);
- parse_ftrace_file(buf, size);
- free(buf);
-}
-
-static void read_event_file(char *sys, unsigned long long size)
-{
- char *buf;
-
- buf = malloc_or_die(size);
- read_or_die(buf, size);
- parse_event_file(buf, size, sys);
- free(buf);
-}
-
-static void read_ftrace_files(void)
-{
- unsigned long long size;
- int count;
- int i;
-
- count = read4();
-
- for (i = 0; i < count; i++) {
- size = read8();
- read_ftrace_file(size);
- }
-}
-
-static void read_event_files(void)
-{
- unsigned long long size;
- char *sys;
- int systems;
- int count;
- int i,x;
-
- systems = read4();
-
- for (i = 0; i < systems; i++) {
- sys = read_string();
-
- count = read4();
- for (x=0; x < count; x++) {
- size = read8();
- read_event_file(sys, size);
- }
- }
-}
-
-struct cpu_data {
- unsigned long long offset;
- unsigned long long size;
- unsigned long long timestamp;
- struct record *next;
- char *page;
- int cpu;
- int index;
- int page_size;
-};
-
-static struct cpu_data *cpu_data;
-
-static void update_cpu_data_index(int cpu)
-{
- cpu_data[cpu].offset += page_size;
- cpu_data[cpu].size -= page_size;
- cpu_data[cpu].index = 0;
-}
-
-static void get_next_page(int cpu)
-{
- off_t save_seek;
- off_t ret;
-
- if (!cpu_data[cpu].page)
- return;
-
- if (read_page) {
- if (cpu_data[cpu].size <= page_size) {
- free(cpu_data[cpu].page);
- cpu_data[cpu].page = NULL;
- return;
- }
-
- update_cpu_data_index(cpu);
-
- /* other parts of the code may expect the pointer to not move */
- save_seek = lseek(input_fd, 0, SEEK_CUR);
-
- ret = lseek(input_fd, cpu_data[cpu].offset, SEEK_SET);
- if (ret == (off_t)-1)
- die("failed to lseek");
- ret = read(input_fd, cpu_data[cpu].page, page_size);
- if (ret < 0)
- die("failed to read page");
-
- /* reset the file pointer back */
- lseek(input_fd, save_seek, SEEK_SET);
-
- return;
- }
-
- munmap(cpu_data[cpu].page, page_size);
- cpu_data[cpu].page = NULL;
-
- if (cpu_data[cpu].size <= page_size)
- return;
-
- update_cpu_data_index(cpu);
-
- cpu_data[cpu].page = mmap(NULL, page_size, PROT_READ, MAP_PRIVATE,
- input_fd, cpu_data[cpu].offset);
- if (cpu_data[cpu].page == MAP_FAILED)
- die("failed to mmap cpu %d at offset 0x%llx",
- cpu, cpu_data[cpu].offset);
-}
-
-static unsigned int type_len4host(unsigned int type_len_ts)
-{
- if (file_bigendian)
- return (type_len_ts >> 27) & ((1 << 5) - 1);
- else
- return type_len_ts & ((1 << 5) - 1);
-}
-
-static unsigned int ts4host(unsigned int type_len_ts)
-{
- if (file_bigendian)
- return type_len_ts & ((1 << 27) - 1);
- else
- return type_len_ts >> 5;
-}
-
-static int calc_index(void *ptr, int cpu)
-{
- return (unsigned long)ptr - (unsigned long)cpu_data[cpu].page;
-}
-
-struct record *trace_peek_data(int cpu)
-{
- struct record *data;
- void *page = cpu_data[cpu].page;
- int idx = cpu_data[cpu].index;
- void *ptr = page + idx;
- unsigned long long extend;
- unsigned int type_len_ts;
- unsigned int type_len;
- unsigned int delta;
- unsigned int length = 0;
-
- if (cpu_data[cpu].next)
- return cpu_data[cpu].next;
-
- if (!page)
- return NULL;
-
- if (!idx) {
- /* FIXME: handle header page */
- if (header_page_ts_size != 8)
- die("expected a long long type for timestamp");
- cpu_data[cpu].timestamp = data2host8(perf_pevent, ptr);
- ptr += 8;
- switch (header_page_size_size) {
- case 4:
- cpu_data[cpu].page_size = data2host4(perf_pevent, ptr);
- ptr += 4;
- break;
- case 8:
- cpu_data[cpu].page_size = data2host8(perf_pevent, ptr);
- ptr += 8;
- break;
- default:
- die("bad long size");
- }
- ptr = cpu_data[cpu].page + header_page_data_offset;
- }
-
-read_again:
- idx = calc_index(ptr, cpu);
-
- if (idx >= cpu_data[cpu].page_size) {
- get_next_page(cpu);
- return trace_peek_data(cpu);
- }
-
- type_len_ts = data2host4(perf_pevent, ptr);
- ptr += 4;
-
- type_len = type_len4host(type_len_ts);
- delta = ts4host(type_len_ts);
-
- switch (type_len) {
- case RINGBUF_TYPE_PADDING:
- if (!delta)
- die("error, hit unexpected end of page");
- length = data2host4(perf_pevent, ptr);
- ptr += 4;
- length *= 4;
- ptr += length;
- goto read_again;
-
- case RINGBUF_TYPE_TIME_EXTEND:
- extend = data2host4(perf_pevent, ptr);
- ptr += 4;
- extend <<= TS_SHIFT;
- extend += delta;
- cpu_data[cpu].timestamp += extend;
- goto read_again;
-
- case RINGBUF_TYPE_TIME_STAMP:
- ptr += 12;
- break;
- case 0:
- length = data2host4(perf_pevent, ptr);
- ptr += 4;
- die("here! length=%d", length);
- break;
- default:
- length = type_len * 4;
- break;
- }
-
- cpu_data[cpu].timestamp += delta;
-
- data = malloc_or_die(sizeof(*data));
- memset(data, 0, sizeof(*data));
-
- data->ts = cpu_data[cpu].timestamp;
- data->size = length;
- data->data = ptr;
- ptr += length;
-
- cpu_data[cpu].index = calc_index(ptr, cpu);
- cpu_data[cpu].next = data;
-
- return data;
-}
-
-struct record *trace_read_data(int cpu)
-{
- struct record *data;
-
- data = trace_peek_data(cpu);
- cpu_data[cpu].next = NULL;
-
- return data;
-}
-
-ssize_t trace_report(int fd, bool __repipe)
-{
- char buf[BUFSIZ];
- char test[] = { 23, 8, 68 };
- char *version;
- int show_version = 0;
- int show_funcs = 0;
- int show_printk = 0;
- ssize_t size;
-
- calc_data_size = 1;
- repipe = __repipe;
-
- input_fd = fd;
-
- read_or_die(buf, 3);
- if (memcmp(buf, test, 3) != 0)
- die("no trace data in the file");
-
- read_or_die(buf, 7);
- if (memcmp(buf, "tracing", 7) != 0)
- die("not a trace file (missing 'tracing' tag)");
-
- version = read_string();
- if (show_version)
- printf("version = %s\n", version);
- free(version);
-
- read_or_die(buf, 1);
- file_bigendian = buf[0];
- host_bigendian = bigendian();
-
- read_trace_init(file_bigendian, host_bigendian);
-
- read_or_die(buf, 1);
- long_size = buf[0];
-
- page_size = read4();
-
- read_header_files();
-
- read_ftrace_files();
- read_event_files();
- read_proc_kallsyms();
- read_ftrace_printk();
-
- size = calc_data_size - 1;
- calc_data_size = 0;
- repipe = false;
-
- if (show_funcs) {
- pevent_print_funcs(perf_pevent);
- return size;
- }
- if (show_printk) {
- pevent_print_printk(perf_pevent);
- return size;
- }
-
- return size;
-}
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c
index cc4f4d5..e97b15a 100644
--- a/tools/perf/util/trace-event-scripting.c
+++ b/tools/perf/util/trace-event-scripting.c
@@ -27,7 +27,7 @@

#include "../perf.h"
#include <lk/util.h>
-#include "trace-event.h"
+#include <trace/trace-event.h>

struct scripting_context *scripting_context;

diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
deleted file mode 100644
index 6597c73..0000000
--- a/tools/perf/util/trace-event.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef _PERF_UTIL_TRACE_EVENT_H
-#define _PERF_UTIL_TRACE_EVENT_H
-
-#include "../../lib/trace/parse-events.h"
-#include "parse-events.h"
-
-extern int header_page_size_size;
-extern int header_page_ts_size;
-extern int header_page_data_offset;
-
-extern bool latency_format;
-extern struct pevent *perf_pevent;
-
-struct scripting_context {
- void *event_data;
-};
-
-enum {
- RINGBUF_TYPE_PADDING = 29,
- RINGBUF_TYPE_TIME_EXTEND = 30,
- RINGBUF_TYPE_TIME_STAMP = 31,
-};
-
-#ifndef TS_SHIFT
-#define TS_SHIFT 27
-#endif
-
-int bigendian(void);
-
-int read_trace_init(int file_bigendian, int host_bigendian);
-
-void print_event(int cpu, void *data, int size, unsigned long long nsecs,
- char *comm);
-
-struct record *trace_read_data(int cpu);
-int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events);
-ssize_t read_tracing_data_size(int fd, struct perf_event_attr *pattrs,
- int nb_events);
-
-int parse_ftrace_file(char *buf, unsigned long size);
-int parse_event_file(char *buf, unsigned long size, char *sys);
-
-struct record *trace_peek_data(int cpu);
-struct event_format *trace_find_event(int type);
-
-unsigned long long
-raw_field_value(struct event_format *event, const char *name, void *data);
-void *raw_field_ptr(struct event_format *event, const char *name, void *data);
-
-void parse_proc_kallsyms(char *file, unsigned int size __unused);
-void parse_ftrace_printk(char *file, unsigned int size __unused);
-
-ssize_t trace_report(int fd, bool repipe);
-
-struct scripting_ops {
- const char *name;
- int (*start_script) (const char *script, int argc, const char **argv);
- int (*stop_script) (void);
- void (*process_event) (int cpu, void *data, int size,
- unsigned long long nsecs, char *comm);
- int (*generate_script) (const char *outfile);
-};
-
-int script_spec_register(const char *spec, struct scripting_ops *ops);
-
-void setup_perl_scripting(void);
-void setup_python_scripting(void);
-
-int trace_parse_common_type(void *data);
-int trace_parse_common_pid(void *data);
-#if 0
-int parse_common_pc(void *data);
-int parse_common_flags(void *data);
-int parse_common_lock_depth(void *data);
-struct event_format *trace_find_event(int id);
-#endif
-struct event_format *trace_find_next_event(struct event_format *event);
-unsigned long long read_size(void *ptr, int size);
-#if 0
-unsigned long long
-raw_field_value(struct event_format *event, const char *name, void *data);
-void *raw_field_ptr(struct event_format *event, const char *name, void *data);
-#endif
-unsigned long long eval_flag(const char *flag);
-
-int common_pc(struct scripting_context *context);
-int common_flags(struct scripting_context *context);
-int common_lock_depth(struct scripting_context *context);
-
-#endif /* _PERF_UTIL_TRACE_EVENT_H */
--
1.7.3.1