1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SRC_FTRACE_READER_EVENT_INFO_CONSTANTS_H_
18 #define SRC_FTRACE_READER_EVENT_INFO_CONSTANTS_H_
19 
20 #include <stdint.h>
21 
22 #include <string>
23 #include <vector>
24 
25 #include "perfetto/base/logging.h"
26 
27 namespace perfetto {
28 
29 enum ProtoFieldType {
30   kProtoDouble = 1,
31   kProtoFloat,
32   kProtoInt32,
33   kProtoInt64,
34   kProtoUint32,
35   kProtoUint64,
36   kProtoSint32,
37   kProtoSint64,
38   kProtoFixed32,
39   kProtoFixed64,
40   kProtoSfixed32,
41   kProtoSfixed64,
42   kProtoBool,
43   kProtoString,
44   kProtoBytes,
45 };
46 
47 enum FtraceFieldType {
48   kFtraceUint8 = 1,
49   kFtraceUint16,
50   kFtraceUint32,
51   kFtraceUint64,
52   kFtraceInt8,
53   kFtraceInt16,
54   kFtraceInt32,
55   kFtraceInt64,
56   kFtraceFixedCString,
57   kFtraceCString,
58   kFtraceStringPtr,
59   kFtraceBool,
60   kFtraceInode32,
61   kFtraceInode64,
62   kFtracePid32,
63   kFtraceCommonPid32,
64   kFtraceDevId32,
65   kFtraceDevId64,
66 };
67 
68 // Joint enum of FtraceFieldType (left) and ProtoFieldType (right).
69 // where there exists a way to convert from the FtraceFieldType
70 // into the ProtoFieldType.
71 enum TranslationStrategy {
72   kUint8ToUint32 = 1,
73   kUint16ToUint32,
74   kUint32ToUint32,
75   kUint32ToUint64,
76   kUint64ToUint64,
77   kInt8ToInt32,
78   kInt16ToInt32,
79   kInt32ToInt32,
80   kInt32ToInt64,
81   kInt64ToInt64,
82   kFixedCStringToString,
83   kCStringToString,
84   kStringPtrToString,
85   kBoolToUint32,
86   kInode32ToUint64,
87   kInode64ToUint64,
88   kPid32ToInt32,
89   kCommonPid32ToInt32,
90   kDevId32ToUint64,
91   kDevId64ToUint64,
92 };
93 
ToString(ProtoFieldType v)94 inline const char* ToString(ProtoFieldType v) {
95   switch (v) {
96     case kProtoDouble:
97       return "double";
98     case kProtoFloat:
99       return "float";
100     case kProtoInt32:
101       return "int32";
102     case kProtoInt64:
103       return "int64";
104     case kProtoUint32:
105       return "uint32";
106     case kProtoUint64:
107       return "uint64";
108     case kProtoSint32:
109       return "sint32";
110     case kProtoSint64:
111       return "sint64";
112     case kProtoFixed32:
113       return "fixed32";
114     case kProtoFixed64:
115       return "fixed64";
116     case kProtoSfixed32:
117       return "sfixed32";
118     case kProtoSfixed64:
119       return "sfixed64";
120     case kProtoBool:
121       return "bool";
122     case kProtoString:
123       return "string";
124     case kProtoBytes:
125       return "bytes";
126   }
127   // For gcc:
128   PERFETTO_CHECK(false);
129   return "";
130 }
131 
ToString(FtraceFieldType v)132 inline const char* ToString(FtraceFieldType v) {
133   switch (v) {
134     case kFtraceUint8:
135       return "uint8";
136     case kFtraceUint16:
137       return "uint16";
138     case kFtraceUint32:
139       return "uint32";
140     case kFtraceUint64:
141       return "uint64";
142     case kFtraceInt8:
143       return "int8";
144     case kFtraceInt16:
145       return "int16";
146     case kFtraceInt32:
147       return "int32";
148     case kFtraceInt64:
149       return "int64";
150     case kFtraceFixedCString:
151       return "fixed length null terminated string";
152     case kFtraceCString:
153       return "null terminated string";
154     case kFtraceStringPtr:
155       return "string ptr";
156     case kFtraceBool:
157       return "bool";
158     case kFtraceInode32:
159       return "inode32";
160     case kFtraceInode64:
161       return "inode64";
162     case kFtracePid32:
163       return "pid32";
164     case kFtraceCommonPid32:
165       return "common_pid32";
166     case kFtraceDevId32:
167       return "devid32";
168     case kFtraceDevId64:
169       return "devid64";
170   }
171   // For gcc:
172   PERFETTO_CHECK(false);
173   return "";
174 }
175 
176 struct Field {
177   Field() = default;
FieldField178   Field(uint16_t offset, uint16_t size)
179       : ftrace_offset(offset), ftrace_size(size) {}
180 
181   uint16_t ftrace_offset;
182   uint16_t ftrace_size;
183   FtraceFieldType ftrace_type;
184   const char* ftrace_name;
185 
186   uint32_t proto_field_id;
187   ProtoFieldType proto_field_type;
188 
189   TranslationStrategy strategy;
190 };
191 
192 struct Event {
193   Event() = default;
EventEvent194   Event(const char* event_name, const char* event_group)
195       : name(event_name), group(event_group) {}
196 
197   const char* name;
198   const char* group;
199   std::vector<Field> fields;
200   uint32_t ftrace_event_id;
201 
202   // Field id of the subevent proto (e.g. PrintFtraceEvent) in the FtraceEvent
203   // parent proto.
204   uint32_t proto_field_id;
205 
206   // 'Size' of the event. Some caveats: some events (e.g. print) end with a null
207   // terminated string of unknown size. This size doesn't include the length of
208   // that string.
209   uint16_t size;
210 };
211 
212 // The compile time information needed to read the raw ftrace buffer.
213 // Specifically for each event we have a proto we fill:
214 //  The event name (e.g. sched_switch)
215 //  The event group  (e.g. sched)
216 //  The the proto field ID of this event in the FtraceEvent proto.
217 //  For each field in the proto:
218 //    The field name (e.g. prev_comm)
219 //    The proto field id for this field
220 //    The proto field type for this field (e.g. kProtoString or kProtoUint32)
221 // The other fields: ftrace_event_id, ftrace_size, ftrace_offset, ftrace_type
222 // are zeroed.
223 std::vector<Event> GetStaticEventInfo();
224 
225 // The compile time information needed to read the common fields from
226 // the raw ftrace buffer.
227 std::vector<Field> GetStaticCommonFieldsInfo();
228 
229 bool SetTranslationStrategy(FtraceFieldType ftrace,
230                             ProtoFieldType proto,
231                             TranslationStrategy* out);
232 
233 Field MakeField(const char* name, uint32_t id, ProtoFieldType type);
234 
235 }  // namespace perfetto
236 
237 #endif  // SRC_FTRACE_READER_EVENT_INFO_CONSTANTS_H_
238