1
2 /*
3 * Copyright (C) 2024 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License";
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include "src/trace_processor/importers/etm/util.h"
19
20 #include <optional>
21
22 #include "perfetto/base/logging.h"
23 #include "src/trace_processor/importers/etm/element_cursor.h"
24
25 namespace perfetto::trace_processor::etm {
26
ToString(ocsd_gen_trc_elem_t type)27 const char* ToString(ocsd_gen_trc_elem_t type) {
28 // This switch also makes sure the range of values for type is compatible with
29 // `ElementTypeMask`.
30 switch (type) {
31 case OCSD_GEN_TRC_ELEM_UNKNOWN:
32 static_assert(
33 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_UNKNOWN));
34 return "UNKNOWN";
35 case OCSD_GEN_TRC_ELEM_NO_SYNC:
36 static_assert(
37 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_NO_SYNC));
38 return "NO_SYNC";
39 case OCSD_GEN_TRC_ELEM_TRACE_ON:
40 static_assert(
41 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_TRACE_ON));
42 return "TRACE_ON";
43 case OCSD_GEN_TRC_ELEM_EO_TRACE:
44 static_assert(
45 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_EO_TRACE));
46 return "EO_TRACE";
47 case OCSD_GEN_TRC_ELEM_PE_CONTEXT:
48 static_assert(
49 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_PE_CONTEXT));
50 return "PE_CONTEXT";
51 case OCSD_GEN_TRC_ELEM_INSTR_RANGE:
52 static_assert(
53 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_INSTR_RANGE));
54 return "INSTR_RANGE";
55 case OCSD_GEN_TRC_ELEM_I_RANGE_NOPATH:
56 static_assert(
57 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_I_RANGE_NOPATH));
58 return "I_RANGE_NOPATH";
59 case OCSD_GEN_TRC_ELEM_ADDR_NACC:
60 static_assert(
61 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_ADDR_NACC));
62 return "ADDR_NACC";
63 case OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN:
64 static_assert(
65 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN));
66 return "ADDR_UNKNOWN";
67 case OCSD_GEN_TRC_ELEM_EXCEPTION:
68 static_assert(
69 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_EXCEPTION));
70 return "EXCEPTION";
71 case OCSD_GEN_TRC_ELEM_EXCEPTION_RET:
72 static_assert(
73 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_EXCEPTION_RET));
74 return "EXCEPTION_RET";
75 case OCSD_GEN_TRC_ELEM_TIMESTAMP:
76 static_assert(
77 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_TIMESTAMP));
78 return "TIMESTAMP";
79 case OCSD_GEN_TRC_ELEM_CYCLE_COUNT:
80 static_assert(
81 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_CYCLE_COUNT));
82 return "CYCLE_COUNT";
83 case OCSD_GEN_TRC_ELEM_EVENT:
84 static_assert(
85 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_EVENT));
86 return "EVENT";
87 case OCSD_GEN_TRC_ELEM_SWTRACE:
88 static_assert(
89 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_SWTRACE));
90 return "SWTRACE";
91 case OCSD_GEN_TRC_ELEM_SYNC_MARKER:
92 static_assert(
93 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_SYNC_MARKER));
94 return "SYNC_MARKER";
95 case OCSD_GEN_TRC_ELEM_MEMTRANS:
96 static_assert(
97 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_MEMTRANS));
98 return "MEMTRANS";
99 case OCSD_GEN_TRC_ELEM_INSTRUMENTATION:
100 static_assert(ElementTypeMask::IsCompatibleValue(
101 OCSD_GEN_TRC_ELEM_INSTRUMENTATION));
102 return "INSTRUMENTATION";
103 case OCSD_GEN_TRC_ELEM_CUSTOM:
104 static_assert(
105 ElementTypeMask::IsCompatibleValue(OCSD_GEN_TRC_ELEM_CUSTOM));
106 return "CUSTOM";
107 }
108 PERFETTO_CHECK(false); // For GCC.
109 }
110
FromString(const char * type_str)111 std::optional<ocsd_gen_trc_elem_t> FromString(const char* type_str) {
112 if (strcmp(type_str, "UNKNOWN") == 0) {
113 return OCSD_GEN_TRC_ELEM_UNKNOWN;
114 }
115 if (strcmp(type_str, "NO_SYNC") == 0) {
116 return OCSD_GEN_TRC_ELEM_NO_SYNC;
117 }
118 if (strcmp(type_str, "TRACE_ON") == 0) {
119 return OCSD_GEN_TRC_ELEM_TRACE_ON;
120 }
121 if (strcmp(type_str, "EO_TRACE") == 0) {
122 return OCSD_GEN_TRC_ELEM_EO_TRACE;
123 }
124 if (strcmp(type_str, "PE_CONTEXT") == 0) {
125 return OCSD_GEN_TRC_ELEM_PE_CONTEXT;
126 }
127 if (strcmp(type_str, "INSTR_RANGE") == 0) {
128 return OCSD_GEN_TRC_ELEM_INSTR_RANGE;
129 }
130 if (strcmp(type_str, "I_RANGE_NOPATH") == 0) {
131 return OCSD_GEN_TRC_ELEM_I_RANGE_NOPATH;
132 }
133 if (strcmp(type_str, "ADDR_NACC") == 0) {
134 return OCSD_GEN_TRC_ELEM_ADDR_NACC;
135 }
136 if (strcmp(type_str, "ADDR_UNKNOWN") == 0) {
137 return OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN;
138 }
139 if (strcmp(type_str, "EXCEPTION") == 0) {
140 return OCSD_GEN_TRC_ELEM_EXCEPTION;
141 }
142 if (strcmp(type_str, "EXCEPTION_RET") == 0) {
143 return OCSD_GEN_TRC_ELEM_EXCEPTION_RET;
144 }
145 if (strcmp(type_str, "TIMESTAMP") == 0) {
146 return OCSD_GEN_TRC_ELEM_TIMESTAMP;
147 }
148 if (strcmp(type_str, "CYCLE_COUNT") == 0) {
149 return OCSD_GEN_TRC_ELEM_CYCLE_COUNT;
150 }
151 if (strcmp(type_str, "EVENT") == 0) {
152 return OCSD_GEN_TRC_ELEM_EVENT;
153 }
154 if (strcmp(type_str, "SWTRACE") == 0) {
155 return OCSD_GEN_TRC_ELEM_SWTRACE;
156 }
157 if (strcmp(type_str, "SYNC_MARKER") == 0) {
158 return OCSD_GEN_TRC_ELEM_SYNC_MARKER;
159 }
160 if (strcmp(type_str, "MEMTRANS") == 0) {
161 return OCSD_GEN_TRC_ELEM_MEMTRANS;
162 }
163 if (strcmp(type_str, "INSTRUMENTATION") == 0) {
164 return OCSD_GEN_TRC_ELEM_INSTRUMENTATION;
165 }
166 if (strcmp(type_str, "CUSTOM") == 0) {
167 return OCSD_GEN_TRC_ELEM_CUSTOM;
168 }
169 return std::nullopt;
170 }
171
ToString(ocsd_isa isa)172 const char* ToString(ocsd_isa isa) {
173 switch (isa) {
174 case ocsd_isa_arm:
175 return "ARM";
176 case ocsd_isa_thumb2:
177 return "THUMB2";
178 case ocsd_isa_aarch64:
179 return "AARCH64";
180 case ocsd_isa_tee:
181 return "TEE";
182 case ocsd_isa_jazelle:
183 return "JAZELLE";
184 case ocsd_isa_custom:
185 return "CUSTOM";
186 case ocsd_isa_unknown:
187 return "UNKNOWN";
188 }
189 PERFETTO_CHECK(false); // For GCC.
190 }
191
ToString(ocsd_instr_type type)192 const char* ToString(ocsd_instr_type type) {
193 switch (type) {
194 case OCSD_INSTR_OTHER:
195 return "OTHER";
196 case OCSD_INSTR_BR:
197 return "BR";
198 case OCSD_INSTR_BR_INDIRECT:
199 return "BR_INDIRECT";
200 case OCSD_INSTR_ISB:
201 return "ISB";
202 case OCSD_INSTR_DSB_DMB:
203 return "DSB_DMB";
204 case OCSD_INSTR_WFI_WFE:
205 return "WFI_WFE";
206 case OCSD_INSTR_TSTART:
207 return "TSTART";
208 }
209 PERFETTO_CHECK(false); // For GCC.
210 }
211
ToString(ocsd_instr_subtype sub_type)212 const char* ToString(ocsd_instr_subtype sub_type) {
213 switch (sub_type) {
214 case OCSD_S_INSTR_NONE:
215 return "NONE";
216 case OCSD_S_INSTR_BR_LINK:
217 return "BR_LINK";
218 case OCSD_S_INSTR_V8_RET:
219 return "V8_RET";
220 case OCSD_S_INSTR_V8_ERET:
221 return "V8_ERET";
222 case OCSD_S_INSTR_V7_IMPLIED_RET:
223 return "V7_IMPLIED_RET";
224 }
225 PERFETTO_CHECK(false); // For GCC.
226 }
227
ToString(ocsd_core_profile_t profile)228 const char* ToString(ocsd_core_profile_t profile) {
229 switch (profile) {
230 case profile_Unknown:
231 return "UNKNOWN";
232 case profile_CortexM:
233 return "CORTEX_M";
234 case profile_CortexR:
235 return "CORTEX_R";
236 case profile_CortexA:
237 return "CORTEX_A";
238 case profile_Custom:
239 return "CUSTOM";
240 }
241 return "UNKNOWN";
242 }
243
ToString(ocsd_arch_version_t ver)244 const char* ToString(ocsd_arch_version_t ver) {
245 switch (ver) {
246 case ARCH_UNKNOWN:
247 return "UNKNOWN";
248 case ARCH_CUSTOM:
249 return "CUSTOM";
250 case ARCH_V7:
251 return "V7";
252 case ARCH_V8:
253 return "V8";
254 case ARCH_V8r3:
255 return "V8_R3";
256 case ARCH_AA64:
257 return "AA64";
258 }
259 return "UNKNOWN";
260 }
261
262 } // namespace perfetto::trace_processor::etm
263