1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Copyright (C) 2009, Steven Rostedt <srostedt@redhat.com>
3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This program is free software; you can redistribute it and/or modify
7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * it under the terms of the GNU General Public License as published by
8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * the Free Software Foundation; version 2 of the License (not later!)
9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This program is distributed in the hope that it will be useful,
11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * but WITHOUT ANY WARRANTY; without even the implied warranty of
12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * GNU General Public License for more details.
14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * You should have received a copy of the GNU General Public License
16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * along with this program; if not, write to the Free Software
17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdio.h>
22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdlib.h>
23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <string.h>
24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <ctype.h>
25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <errno.h>
26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../perf.h"
28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util.h"
29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "trace-event.h"
30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct pevent *read_trace_init(int file_bigendian, int host_bigendian)
32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent *pevent = pevent_alloc();
34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent != NULL) {
36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT);
37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent_set_file_bigendian(pevent, file_bigendian);
38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent_set_host_bigendian(pevent, host_bigendian);
39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pevent;
42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int get_common_field(struct scripting_context *context,
45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			    int *offset, int *size, const char *type)
46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent *pevent = context->pevent;
48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct event_format *event;
49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!*size) {
52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!pevent->events)
53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 0;
54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		event = pevent->events[0];
56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		field = pevent_find_common_field(event, type);
57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!field)
58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return 0;
59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*offset = field->offset;
60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*size = field->size;
61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pevent_read_number(pevent, context->event_data + *offset, *size);
64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint common_lock_depth(struct scripting_context *context)
67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static int offset;
69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static int size;
70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret;
71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = get_common_field(context, &size, &offset,
73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       "common_lock_depth");
74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ret < 0)
75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint common_flags(struct scripting_context *context)
81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static int offset;
83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static int size;
84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret;
85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = get_common_field(context, &size, &offset,
87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       "common_flags");
88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ret < 0)
89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint common_pc(struct scripting_context *context)
95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static int offset;
97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static int size;
98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret;
99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = get_common_field(context, &size, &offset,
101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			       "common_preempt_count");
102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (ret < 0)
103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengunsigned long long
109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengraw_field_value(struct event_format *event, const char *name, void *data)
110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long val;
113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = pevent_find_any_field(event, name);
115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field)
116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0ULL;
117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent_read_number_field(field, data, &val);
119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return val;
121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid *raw_field_ptr(struct event_format *event, const char *name, void *data)
124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct format_field *field;
126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	field = pevent_find_any_field(event, name);
128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!field)
129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (field->flags & FIELD_IS_DYNAMIC) {
132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		int offset;
133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		offset = *(int *)(data + field->offset);
135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		offset &= 0xffff;
136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return data + offset;
138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return data + field->offset;
141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint trace_parse_common_type(struct pevent *pevent, void *data)
144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_record record;
146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	record.data = data;
148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pevent_data_type(pevent, &record);
149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint trace_parse_common_pid(struct pevent *pevent, void *data)
152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_record record;
154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	record.data = data;
156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pevent_data_pid(pevent, &record);
157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengunsigned long long read_size(struct event_format *event, void *ptr, int size)
160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pevent_read_number(event->pevent, ptr, size);
162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid event_format__print(struct event_format *event,
165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 int cpu, void *data, int size)
166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pevent_record record;
168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct trace_seq s;
169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	memset(&record, 0, sizeof(record));
171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	record.cpu = cpu;
172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	record.size = size;
173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	record.data = data;
174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	trace_seq_init(&s);
176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent_event_info(&s, event, &record);
177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	trace_seq_do_printf(&s);
178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid parse_proc_kallsyms(struct pevent *pevent,
181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 char *file, unsigned int size __maybe_unused)
182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long addr;
184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *func;
185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *line;
186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *next = NULL;
187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *addr_str;
188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *mod;
189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *fmt = NULL;
190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	line = strtok_r(file, "\n", &next);
192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (line) {
193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		mod = NULL;
194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		addr_str = strtok_r(line, " ", &fmt);
195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		addr = strtoull(addr_str, NULL, 16);
196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* skip character */
197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		strtok_r(NULL, " ", &fmt);
198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		func = strtok_r(NULL, "\t", &fmt);
199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		mod = strtok_r(NULL, "]", &fmt);
200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* truncate the extra '[' */
201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (mod)
202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			mod = mod + 1;
203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent_register_function(pevent, func, addr, mod);
205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		line = strtok_r(NULL, "\n", &next);
207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid parse_ftrace_printk(struct pevent *pevent,
211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 char *file, unsigned int size __maybe_unused)
212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long addr;
214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *printk;
215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *line;
216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *next = NULL;
217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *addr_str;
218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *fmt;
219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	line = strtok_r(file, "\n", &next);
221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (line) {
222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		addr_str = strtok_r(line, ":", &fmt);
223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!addr_str) {
224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			warning("printk format with empty entry");
225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		addr = strtoull(addr_str, NULL, 16);
228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/* fmt still has a space, skip it */
229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		printk = strdup(fmt+1);
230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		line = strtok_r(NULL, "\n", &next);
231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pevent_register_print_string(pevent, printk, addr);
232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size)
236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pevent_parse_event(pevent, buf, size, "ftrace");
238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint parse_event_file(struct pevent *pevent,
241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     char *buf, unsigned long size, char *sys)
242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pevent_parse_event(pevent, buf, size, sys);
244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct event_format *trace_find_next_event(struct pevent *pevent,
247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					   struct event_format *event)
248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static int idx;
250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!pevent || !pevent->events)
252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!event) {
255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		idx = 0;
256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return pevent->events[0];
257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (idx < pevent->nr_events && event == pevent->events[idx]) {
260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		idx++;
261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (idx == pevent->nr_events)
262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return NULL;
263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return pevent->events[idx];
264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (idx = 1; idx < pevent->nr_events; idx++) {
267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (event == pevent->events[idx - 1])
268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return pevent->events[idx];
269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return NULL;
271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct flag {
274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *name;
275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long long value;
276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic const struct flag flags[] = {
279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "HI_SOFTIRQ", 0 },
280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "TIMER_SOFTIRQ", 1 },
281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "NET_TX_SOFTIRQ", 2 },
282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "NET_RX_SOFTIRQ", 3 },
283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "BLOCK_SOFTIRQ", 4 },
284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "BLOCK_IOPOLL_SOFTIRQ", 5 },
285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "TASKLET_SOFTIRQ", 6 },
286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "SCHED_SOFTIRQ", 7 },
287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "HRTIMER_SOFTIRQ", 8 },
288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "RCU_SOFTIRQ", 9 },
289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "HRTIMER_NORESTART", 0 },
291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "HRTIMER_RESTART", 1 },
292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengunsigned long long eval_flag(const char *flag)
295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * Some flags in the format files do not get converted.
300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * If the flag is not numeric, see if it is something that
301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * we already know about.
302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 */
303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (isdigit(flag[0]))
304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return strtoull(flag, NULL, 0);
305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++)
307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (strcmp(flags[i].name, flag) == 0)
308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return flags[i].value;
309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
312