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