1 /*
2 * Copyright (c) 2013-2019, Intel Corporation
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * * Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * * Neither the name of Intel Corporation nor the names of its contributors
13 * may be used to endorse or promote products derived from this software
14 * without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "pt_decoder_function.h"
30 #include "pt_packet_decoder.h"
31 #include "pt_query_decoder.h"
32 #include "pt_opcodes.h"
33
34 #include "intel-pt.h"
35
36
37 const struct pt_decoder_function pt_decode_unknown = {
38 /* .packet = */ pt_pkt_decode_unknown,
39 /* .decode = */ pt_qry_decode_unknown,
40 /* .header = */ pt_qry_decode_unknown,
41 /* .flags = */ pdff_unknown
42 };
43
44 const struct pt_decoder_function pt_decode_pad = {
45 /* .packet = */ pt_pkt_decode_pad,
46 /* .decode = */ pt_qry_decode_pad,
47 /* .header = */ pt_qry_decode_pad,
48 /* .flags = */ pdff_pad
49 };
50
51 const struct pt_decoder_function pt_decode_psb = {
52 /* .packet = */ pt_pkt_decode_psb,
53 /* .decode = */ pt_qry_decode_psb,
54 /* .header = */ NULL,
55 /* .flags = */ 0
56 };
57
58 const struct pt_decoder_function pt_decode_tip = {
59 /* .packet = */ pt_pkt_decode_tip,
60 /* .decode = */ pt_qry_decode_tip,
61 /* .header = */ NULL,
62 /* .flags = */ pdff_tip
63 };
64
65 const struct pt_decoder_function pt_decode_tnt_8 = {
66 /* .packet = */ pt_pkt_decode_tnt_8,
67 /* .decode = */ pt_qry_decode_tnt_8,
68 /* .header = */ NULL,
69 /* .flags = */ pdff_tnt
70 };
71
72 const struct pt_decoder_function pt_decode_tnt_64 = {
73 /* .packet = */ pt_pkt_decode_tnt_64,
74 /* .decode = */ pt_qry_decode_tnt_64,
75 /* .header = */ NULL,
76 /* .flags = */ pdff_tnt
77 };
78
79 const struct pt_decoder_function pt_decode_tip_pge = {
80 /* .packet = */ pt_pkt_decode_tip_pge,
81 /* .decode = */ pt_qry_decode_tip_pge,
82 /* .header = */ NULL,
83 /* .flags = */ pdff_event
84 };
85
86 const struct pt_decoder_function pt_decode_tip_pgd = {
87 /* .packet = */ pt_pkt_decode_tip_pgd,
88 /* .decode = */ pt_qry_decode_tip_pgd,
89 /* .header = */ NULL,
90 /* .flags = */ pdff_event
91 };
92
93 const struct pt_decoder_function pt_decode_fup = {
94 /* .packet = */ pt_pkt_decode_fup,
95 /* .decode = */ pt_qry_decode_fup,
96 /* .header = */ pt_qry_header_fup,
97 /* .flags = */ pdff_fup
98 };
99
100 const struct pt_decoder_function pt_decode_pip = {
101 /* .packet = */ pt_pkt_decode_pip,
102 /* .decode = */ pt_qry_decode_pip,
103 /* .header = */ pt_qry_header_pip,
104 /* .flags = */ pdff_event
105 };
106
107 const struct pt_decoder_function pt_decode_ovf = {
108 /* .packet = */ pt_pkt_decode_ovf,
109 /* .decode = */ pt_qry_decode_ovf,
110 /* .header = */ NULL,
111 /* .flags = */ pdff_psbend | pdff_event
112 };
113
114 const struct pt_decoder_function pt_decode_mode = {
115 /* .packet = */ pt_pkt_decode_mode,
116 /* .decode = */ pt_qry_decode_mode,
117 /* .header = */ pt_qry_header_mode,
118 /* .flags = */ pdff_event
119 };
120
121 const struct pt_decoder_function pt_decode_psbend = {
122 /* .packet = */ pt_pkt_decode_psbend,
123 /* .decode = */ pt_qry_decode_psbend,
124 /* .header = */ NULL,
125 /* .flags = */ pdff_psbend
126 };
127
128 const struct pt_decoder_function pt_decode_tsc = {
129 /* .packet = */ pt_pkt_decode_tsc,
130 /* .decode = */ pt_qry_decode_tsc,
131 /* .header = */ pt_qry_header_tsc,
132 /* .flags = */ pdff_timing
133 };
134
135 const struct pt_decoder_function pt_decode_cbr = {
136 /* .packet = */ pt_pkt_decode_cbr,
137 /* .decode = */ pt_qry_decode_cbr,
138 /* .header = */ pt_qry_header_cbr,
139 /* .flags = */ pdff_timing | pdff_event
140 };
141
142 const struct pt_decoder_function pt_decode_tma = {
143 /* .packet = */ pt_pkt_decode_tma,
144 /* .decode = */ pt_qry_decode_tma,
145 /* .header = */ pt_qry_decode_tma,
146 /* .flags = */ pdff_timing
147 };
148
149 const struct pt_decoder_function pt_decode_mtc = {
150 /* .packet = */ pt_pkt_decode_mtc,
151 /* .decode = */ pt_qry_decode_mtc,
152 /* .header = */ pt_qry_decode_mtc,
153 /* .flags = */ pdff_timing
154 };
155
156 const struct pt_decoder_function pt_decode_cyc = {
157 /* .packet = */ pt_pkt_decode_cyc,
158 /* .decode = */ pt_qry_decode_cyc,
159 /* .header = */ pt_qry_decode_cyc,
160 /* .flags = */ pdff_timing
161 };
162
163 const struct pt_decoder_function pt_decode_stop = {
164 /* .packet = */ pt_pkt_decode_stop,
165 /* .decode = */ pt_qry_decode_stop,
166 /* .header = */ NULL,
167 /* .flags = */ pdff_event
168 };
169
170 const struct pt_decoder_function pt_decode_vmcs = {
171 /* .packet = */ pt_pkt_decode_vmcs,
172 /* .decode = */ pt_qry_decode_vmcs,
173 /* .header = */ pt_qry_header_vmcs,
174 /* .flags = */ pdff_event
175 };
176
177 const struct pt_decoder_function pt_decode_mnt = {
178 /* .packet = */ pt_pkt_decode_mnt,
179 /* .decode = */ pt_qry_decode_mnt,
180 /* .header = */ pt_qry_header_mnt,
181 /* .flags = */ pdff_event
182 };
183
184 const struct pt_decoder_function pt_decode_exstop = {
185 /* .packet = */ pt_pkt_decode_exstop,
186 /* .decode = */ pt_qry_decode_exstop,
187 /* .header = */ NULL,
188 /* .flags = */ pdff_event
189 };
190
191 const struct pt_decoder_function pt_decode_mwait = {
192 /* .packet = */ pt_pkt_decode_mwait,
193 /* .decode = */ pt_qry_decode_mwait,
194 /* .header = */ NULL,
195 /* .flags = */ pdff_event
196 };
197
198 const struct pt_decoder_function pt_decode_pwre = {
199 /* .packet = */ pt_pkt_decode_pwre,
200 /* .decode = */ pt_qry_decode_pwre,
201 /* .header = */ NULL,
202 /* .flags = */ pdff_event
203 };
204
205 const struct pt_decoder_function pt_decode_pwrx = {
206 /* .packet = */ pt_pkt_decode_pwrx,
207 /* .decode = */ pt_qry_decode_pwrx,
208 /* .header = */ NULL,
209 /* .flags = */ pdff_event
210 };
211
212 const struct pt_decoder_function pt_decode_ptw = {
213 /* .packet = */ pt_pkt_decode_ptw,
214 /* .decode = */ pt_qry_decode_ptw,
215 /* .header = */ NULL,
216 /* .flags = */ pdff_event
217 };
218
219
pt_df_fetch(const struct pt_decoder_function ** dfun,const uint8_t * pos,const struct pt_config * config)220 int pt_df_fetch(const struct pt_decoder_function **dfun, const uint8_t *pos,
221 const struct pt_config *config)
222 {
223 const uint8_t *begin, *end;
224 uint8_t opc, ext, ext2;
225
226 if (!dfun || !config)
227 return -pte_internal;
228
229 /* Clear the decode function in case of errors. */
230 *dfun = NULL;
231
232 begin = config->begin;
233 end = config->end;
234
235 if (!pos || (pos < begin) || (end < pos))
236 return -pte_nosync;
237
238 if (pos == end)
239 return -pte_eos;
240
241 opc = *pos++;
242 switch (opc) {
243 default:
244 /* Check opcodes that require masking. */
245 if ((opc & pt_opm_tnt_8) == pt_opc_tnt_8) {
246 *dfun = &pt_decode_tnt_8;
247 return 0;
248 }
249
250 if ((opc & pt_opm_cyc) == pt_opc_cyc) {
251 *dfun = &pt_decode_cyc;
252 return 0;
253 }
254
255 if ((opc & pt_opm_tip) == pt_opc_tip) {
256 *dfun = &pt_decode_tip;
257 return 0;
258 }
259
260 if ((opc & pt_opm_fup) == pt_opc_fup) {
261 *dfun = &pt_decode_fup;
262 return 0;
263 }
264
265 if ((opc & pt_opm_tip) == pt_opc_tip_pge) {
266 *dfun = &pt_decode_tip_pge;
267 return 0;
268 }
269
270 if ((opc & pt_opm_tip) == pt_opc_tip_pgd) {
271 *dfun = &pt_decode_tip_pgd;
272 return 0;
273 }
274
275 *dfun = &pt_decode_unknown;
276 return 0;
277
278 case pt_opc_pad:
279 *dfun = &pt_decode_pad;
280 return 0;
281
282 case pt_opc_mode:
283 *dfun = &pt_decode_mode;
284 return 0;
285
286 case pt_opc_tsc:
287 *dfun = &pt_decode_tsc;
288 return 0;
289
290 case pt_opc_mtc:
291 *dfun = &pt_decode_mtc;
292 return 0;
293
294 case pt_opc_ext:
295 if (pos == end)
296 return -pte_eos;
297
298 ext = *pos++;
299 switch (ext) {
300 default:
301 /* Check opcodes that require masking. */
302 if ((ext & pt_opm_ptw) == pt_ext_ptw) {
303 *dfun = &pt_decode_ptw;
304 return 0;
305 }
306
307 *dfun = &pt_decode_unknown;
308 return 0;
309
310 case pt_ext_psb:
311 *dfun = &pt_decode_psb;
312 return 0;
313
314 case pt_ext_ovf:
315 *dfun = &pt_decode_ovf;
316 return 0;
317
318 case pt_ext_tnt_64:
319 *dfun = &pt_decode_tnt_64;
320 return 0;
321
322 case pt_ext_psbend:
323 *dfun = &pt_decode_psbend;
324 return 0;
325
326 case pt_ext_cbr:
327 *dfun = &pt_decode_cbr;
328 return 0;
329
330 case pt_ext_pip:
331 *dfun = &pt_decode_pip;
332 return 0;
333
334 case pt_ext_tma:
335 *dfun = &pt_decode_tma;
336 return 0;
337
338 case pt_ext_stop:
339 *dfun = &pt_decode_stop;
340 return 0;
341
342 case pt_ext_vmcs:
343 *dfun = &pt_decode_vmcs;
344 return 0;
345
346 case pt_ext_exstop:
347 case pt_ext_exstop_ip:
348 *dfun = &pt_decode_exstop;
349 return 0;
350
351 case pt_ext_mwait:
352 *dfun = &pt_decode_mwait;
353 return 0;
354
355 case pt_ext_pwre:
356 *dfun = &pt_decode_pwre;
357 return 0;
358
359 case pt_ext_pwrx:
360 *dfun = &pt_decode_pwrx;
361 return 0;
362
363 case pt_ext_ext2:
364 if (pos == end)
365 return -pte_eos;
366
367 ext2 = *pos++;
368 switch (ext2) {
369 default:
370 *dfun = &pt_decode_unknown;
371 return 0;
372
373 case pt_ext2_mnt:
374 *dfun = &pt_decode_mnt;
375 return 0;
376 }
377 }
378 }
379 }
380