xref: /openbmc/linux/tools/perf/util/trace-event.c (revision c3168b0db93ad5ffeede4ecdf807dab64270f55d)
129f5ffd3SJiri Olsa 
297978b3eSJiri Olsa #include <stdio.h>
397978b3eSJiri Olsa #include <unistd.h>
497978b3eSJiri Olsa #include <stdlib.h>
597978b3eSJiri Olsa #include <errno.h>
697978b3eSJiri Olsa #include <sys/types.h>
797978b3eSJiri Olsa #include <sys/stat.h>
897978b3eSJiri Olsa #include <fcntl.h>
997978b3eSJiri Olsa #include <linux/kernel.h>
1029f5ffd3SJiri Olsa #include <traceevent/event-parse.h>
1129f5ffd3SJiri Olsa #include "trace-event.h"
12*c3168b0dSArnaldo Carvalho de Melo #include "machine.h"
1397978b3eSJiri Olsa #include "util.h"
1497978b3eSJiri Olsa 
1597978b3eSJiri Olsa /*
1697978b3eSJiri Olsa  * global trace_event object used by trace_event__tp_format
1797978b3eSJiri Olsa  *
1897978b3eSJiri Olsa  * TODO There's no cleanup call for this. Add some sort of
1997978b3eSJiri Olsa  * __exit function support and call trace_event__cleanup
2097978b3eSJiri Olsa  * there.
2197978b3eSJiri Olsa  */
2297978b3eSJiri Olsa static struct trace_event tevent;
23*c3168b0dSArnaldo Carvalho de Melo static bool tevent_initialized;
2429f5ffd3SJiri Olsa 
2529f5ffd3SJiri Olsa int trace_event__init(struct trace_event *t)
2629f5ffd3SJiri Olsa {
2729f5ffd3SJiri Olsa 	struct pevent *pevent = pevent_alloc();
2829f5ffd3SJiri Olsa 
2929f5ffd3SJiri Olsa 	if (pevent) {
3029f5ffd3SJiri Olsa 		t->plugin_list = traceevent_load_plugins(pevent);
3129f5ffd3SJiri Olsa 		t->pevent  = pevent;
3229f5ffd3SJiri Olsa 	}
3329f5ffd3SJiri Olsa 
3429f5ffd3SJiri Olsa 	return pevent ? 0 : -1;
3529f5ffd3SJiri Olsa }
3629f5ffd3SJiri Olsa 
37*c3168b0dSArnaldo Carvalho de Melo static int trace_event__init2(void)
38*c3168b0dSArnaldo Carvalho de Melo {
39*c3168b0dSArnaldo Carvalho de Melo 	int be = traceevent_host_bigendian();
40*c3168b0dSArnaldo Carvalho de Melo 	struct pevent *pevent;
41*c3168b0dSArnaldo Carvalho de Melo 
42*c3168b0dSArnaldo Carvalho de Melo 	if (trace_event__init(&tevent))
43*c3168b0dSArnaldo Carvalho de Melo 		return -1;
44*c3168b0dSArnaldo Carvalho de Melo 
45*c3168b0dSArnaldo Carvalho de Melo 	pevent = tevent.pevent;
46*c3168b0dSArnaldo Carvalho de Melo 	pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT);
47*c3168b0dSArnaldo Carvalho de Melo 	pevent_set_file_bigendian(pevent, be);
48*c3168b0dSArnaldo Carvalho de Melo 	pevent_set_host_bigendian(pevent, be);
49*c3168b0dSArnaldo Carvalho de Melo 	tevent_initialized = true;
50*c3168b0dSArnaldo Carvalho de Melo 	return 0;
51*c3168b0dSArnaldo Carvalho de Melo }
52*c3168b0dSArnaldo Carvalho de Melo 
53*c3168b0dSArnaldo Carvalho de Melo int trace_event__register_resolver(struct machine *machine)
54*c3168b0dSArnaldo Carvalho de Melo {
55*c3168b0dSArnaldo Carvalho de Melo 	if (!tevent_initialized && trace_event__init2())
56*c3168b0dSArnaldo Carvalho de Melo 		return -1;
57*c3168b0dSArnaldo Carvalho de Melo 
58*c3168b0dSArnaldo Carvalho de Melo 	return pevent_set_function_resolver(tevent.pevent,
59*c3168b0dSArnaldo Carvalho de Melo 					    machine__resolve_kernel_addr,
60*c3168b0dSArnaldo Carvalho de Melo 					    machine);
61*c3168b0dSArnaldo Carvalho de Melo }
62*c3168b0dSArnaldo Carvalho de Melo 
6329f5ffd3SJiri Olsa void trace_event__cleanup(struct trace_event *t)
6429f5ffd3SJiri Olsa {
658d0c2224SNamhyung Kim 	traceevent_unload_plugins(t->plugin_list, t->pevent);
6629f5ffd3SJiri Olsa 	pevent_free(t->pevent);
6729f5ffd3SJiri Olsa }
6897978b3eSJiri Olsa 
6997978b3eSJiri Olsa static struct event_format*
7097978b3eSJiri Olsa tp_format(const char *sys, const char *name)
7197978b3eSJiri Olsa {
7297978b3eSJiri Olsa 	struct pevent *pevent = tevent.pevent;
7397978b3eSJiri Olsa 	struct event_format *event = NULL;
7497978b3eSJiri Olsa 	char path[PATH_MAX];
7597978b3eSJiri Olsa 	size_t size;
7697978b3eSJiri Olsa 	char *data;
7797978b3eSJiri Olsa 
7897978b3eSJiri Olsa 	scnprintf(path, PATH_MAX, "%s/%s/%s/format",
7997978b3eSJiri Olsa 		  tracing_events_path, sys, name);
8097978b3eSJiri Olsa 
8197978b3eSJiri Olsa 	if (filename__read_str(path, &data, &size))
8297978b3eSJiri Olsa 		return NULL;
8397978b3eSJiri Olsa 
8497978b3eSJiri Olsa 	pevent_parse_format(pevent, &event, data, size, sys);
8597978b3eSJiri Olsa 
8697978b3eSJiri Olsa 	free(data);
8797978b3eSJiri Olsa 	return event;
8897978b3eSJiri Olsa }
8997978b3eSJiri Olsa 
9097978b3eSJiri Olsa struct event_format*
9197978b3eSJiri Olsa trace_event__tp_format(const char *sys, const char *name)
9297978b3eSJiri Olsa {
93*c3168b0dSArnaldo Carvalho de Melo 	if (!tevent_initialized && trace_event__init2())
9497978b3eSJiri Olsa 		return NULL;
9597978b3eSJiri Olsa 
9697978b3eSJiri Olsa 	return tp_format(sys, name);
9797978b3eSJiri Olsa }
98