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