]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/processor-trace/libipt/src/pt_decoder_function.c
Import Intel Processor Trace decoder library from
[FreeBSD/FreeBSD.git] / contrib / processor-trace / libipt / src / pt_decoder_function.c
1 /*
2  * Copyright (c) 2013-2018, 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
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 }