xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/fuchsia/fuchsia_trace_utils.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2019 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_TRACE_PROCESSOR_IMPORTERS_FUCHSIA_FUCHSIA_TRACE_UTILS_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_FUCHSIA_FUCHSIA_TRACE_UTILS_H_
19 
20 #include <stddef.h>
21 #include <stdint.h>
22 #include <functional>
23 
24 #include "perfetto/ext/base/string_view.h"
25 #include "perfetto/trace_processor/trace_blob_view.h"
26 #include "src/trace_processor/importers/fuchsia/fuchsia_record.h"
27 #include "src/trace_processor/storage/trace_storage.h"
28 
29 namespace perfetto {
30 namespace trace_processor {
31 namespace fuchsia_trace_utils {
32 
33 template <class T>
ReadField(uint64_t word,size_t begin,size_t end)34 T ReadField(uint64_t word, size_t begin, size_t end) {
35   return static_cast<T>((word >> begin) &
36                         ((uint64_t(1) << (end - begin + 1)) - 1));
37 }
38 
39 bool IsInlineString(uint32_t);
40 bool IsInlineThread(uint32_t);
41 int64_t TicksToNs(uint64_t ticks, uint64_t ticks_per_second);
42 
43 class ArgValue {
44  public:
45   enum ArgType {
46     kNull,
47     kInt32,
48     kUint32,
49     kInt64,
50     kUint64,
51     kDouble,
52     kString,
53     kPointer,
54     kKoid,
55     kBool,
56     kUnknown,
57   };
58 
Null()59   static ArgValue Null() {
60     ArgValue v;
61     v.type_ = ArgType::kNull;
62     v.int32_ = 0;
63     return v;
64   }
65 
Int32(int32_t value)66   static ArgValue Int32(int32_t value) {
67     ArgValue v;
68     v.type_ = ArgType::kInt32;
69     v.int32_ = value;
70     return v;
71   }
72 
Uint32(uint32_t value)73   static ArgValue Uint32(uint32_t value) {
74     ArgValue v;
75     v.type_ = ArgType::kUint32;
76     v.uint32_ = value;
77     return v;
78   }
79 
Int64(int64_t value)80   static ArgValue Int64(int64_t value) {
81     ArgValue v;
82     v.type_ = ArgType::kInt64;
83     v.int64_ = value;
84     return v;
85   }
86 
Uint64(uint64_t value)87   static ArgValue Uint64(uint64_t value) {
88     ArgValue v;
89     v.type_ = ArgType::kUint64;
90     v.uint64_ = value;
91     return v;
92   }
93 
Double(double value)94   static ArgValue Double(double value) {
95     ArgValue v;
96     v.type_ = ArgType::kDouble;
97     v.double_ = value;
98     return v;
99   }
100 
String(StringId value)101   static ArgValue String(StringId value) {
102     ArgValue v;
103     v.type_ = ArgType::kString;
104     v.string_ = value;
105     return v;
106   }
107 
Pointer(uint64_t value)108   static ArgValue Pointer(uint64_t value) {
109     ArgValue v;
110     v.type_ = ArgType::kPointer;
111     v.pointer_ = value;
112     return v;
113   }
114 
Koid(uint64_t value)115   static ArgValue Koid(uint64_t value) {
116     ArgValue v;
117     v.type_ = ArgType::kKoid;
118     v.koid_ = value;
119     return v;
120   }
121 
Bool(bool value)122   static ArgValue Bool(bool value) {
123     ArgValue v;
124     v.type_ = ArgType::kBool;
125     v.bool_ = value;
126     return v;
127   }
128 
Unknown()129   static ArgValue Unknown() {
130     ArgValue v;
131     v.type_ = ArgType::kUnknown;
132     v.int32_ = 0;
133     return v;
134   }
135 
Type()136   ArgType Type() const { return type_; }
137 
Int32()138   int32_t Int32() const {
139     PERFETTO_DCHECK(type_ == ArgType::kInt32);
140     return int32_;
141   }
142 
Uint32()143   uint32_t Uint32() const {
144     PERFETTO_DCHECK(type_ == ArgType::kUint32);
145     return uint32_;
146   }
147 
Int64()148   int64_t Int64() const {
149     PERFETTO_DCHECK(type_ == ArgType::kInt64);
150     return int64_;
151   }
152 
Uint64()153   uint64_t Uint64() const {
154     PERFETTO_DCHECK(type_ == ArgType::kUint64);
155     return uint64_;
156   }
157 
Double()158   double Double() const {
159     PERFETTO_DCHECK(type_ == ArgType::kDouble);
160     return double_;
161   }
162 
String()163   StringId String() const {
164     PERFETTO_DCHECK(type_ == ArgType::kString);
165     return string_;
166   }
167 
Pointer()168   uint64_t Pointer() const {
169     PERFETTO_DCHECK(type_ == ArgType::kPointer);
170     return pointer_;
171   }
172 
Koid()173   uint64_t Koid() const {
174     PERFETTO_DCHECK(type_ == ArgType::kKoid);
175     return koid_;
176   }
177 
Bool()178   uint64_t Bool() const {
179     PERFETTO_DCHECK(type_ == ArgType::kBool);
180     return bool_;
181   }
182 
183   Variadic ToStorageVariadic(TraceStorage*) const;
184 
185  private:
186   ArgType type_;
187   union {
188     int32_t int32_;
189     uint32_t uint32_;
190     int64_t int64_;
191     uint64_t uint64_;
192     double double_;
193     StringId string_;
194     uint64_t pointer_;
195     uint64_t koid_;
196     bool bool_;
197   };
198 };
199 
200 // This class maintains a location into the record, with helper functions to
201 // read various trace data from the current location in a safe manner.
202 //
203 // In the context of Fuchsia trace records, a "word" is defined as 64 bits
204 // regardless of platform. For more information, see
205 // https://fuchsia.googlesource.com/fuchsia/+/refs/heads/master/docs/development/tracing/trace-format/
206 class RecordCursor {
207  public:
RecordCursor(const uint8_t * begin,size_t length)208   RecordCursor(const uint8_t* begin, size_t length)
209       : begin_(begin), end_(begin + length), word_index_(0) {}
210 
211   size_t WordIndex();
212   void SetWordIndex(size_t index);
213 
214   bool ReadTimestamp(uint64_t ticks_per_second, int64_t* ts_out);
215   bool ReadInlineString(uint32_t string_ref_or_len,
216                         base::StringView* string_out);
217   bool ReadInlineThread(FuchsiaThreadInfo* thread_out);
218 
219   bool ReadInt64(int64_t* out);
220   bool ReadUint64(uint64_t* out);
221   bool ReadDouble(double* out);
222   bool ReadBlob(size_t num_bytes, std::vector<uint8_t>& out);
223 
224  private:
225   bool ReadWords(size_t num_words, const uint8_t** data_out);
226 
227   const uint8_t* begin_;
228   const uint8_t* end_;
229   size_t word_index_;
230 };
231 
232 }  // namespace fuchsia_trace_utils
233 }  // namespace trace_processor
234 }  // namespace perfetto
235 
236 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_FUCHSIA_FUCHSIA_TRACE_UTILS_H_
237