1/*
2 * Copyright (c) 2014-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 "ptunit.h"
30
31#include "pt_decoder_function.h"
32#include "pt_packet_decoder.h"
33#include "pt_query_decoder.h"
34#include "pt_encoder.h"
35#include "pt_opcodes.h"
36
37#include "intel-pt.h"
38
39
40/* A test fixture for decoder function fetch tests. */
41struct fetch_fixture {
42	/* The trace buffer. */
43	uint8_t buffer[1024];
44
45	/* A trace configuration. */
46	struct pt_config config;
47
48	/* A trace encoder. */
49	struct pt_encoder encoder;
50
51	/* The test fixture initialization and finalization functions. */
52	struct ptunit_result (*init)(struct fetch_fixture *);
53	struct ptunit_result (*fini)(struct fetch_fixture *);
54};
55
56static struct ptunit_result ffix_init(struct fetch_fixture *ffix)
57{
58	memset(ffix->buffer, pt_opc_bad, sizeof(ffix->buffer));
59
60	memset(&ffix->config, 0, sizeof(ffix->config));
61	ffix->config.size = sizeof(ffix->config);
62	ffix->config.begin = ffix->buffer;
63	ffix->config.end = ffix->buffer + sizeof(ffix->buffer);
64
65	pt_encoder_init(&ffix->encoder, &ffix->config);
66
67	return ptu_passed();
68}
69
70static struct ptunit_result ffix_fini(struct fetch_fixture *ffix)
71{
72	pt_encoder_fini(&ffix->encoder);
73
74	return ptu_passed();
75}
76
77
78static struct ptunit_result fetch_null(struct fetch_fixture *ffix)
79{
80	const struct pt_decoder_function *dfun;
81	int errcode;
82
83	errcode = pt_df_fetch(NULL, ffix->config.begin, &ffix->config);
84	ptu_int_eq(errcode, -pte_internal);
85
86	errcode = pt_df_fetch(&dfun, NULL, &ffix->config);
87	ptu_int_eq(errcode, -pte_nosync);
88
89	errcode = pt_df_fetch(&dfun, ffix->config.begin, NULL);
90	ptu_int_eq(errcode, -pte_internal);
91
92	return ptu_passed();
93}
94
95static struct ptunit_result fetch_empty(struct fetch_fixture *ffix)
96{
97	const struct pt_decoder_function *dfun;
98	int errcode;
99
100	errcode = pt_df_fetch(&dfun, ffix->config.end, &ffix->config);
101	ptu_int_eq(errcode, -pte_eos);
102
103	return ptu_passed();
104}
105
106static struct ptunit_result fetch_unknown(struct fetch_fixture *ffix)
107{
108	const struct pt_decoder_function *dfun;
109	int errcode;
110
111	ffix->config.begin[0] = pt_opc_bad;
112
113	errcode = pt_df_fetch(&dfun, ffix->config.begin, &ffix->config);
114	ptu_int_eq(errcode, 0);
115	ptu_ptr_eq(dfun, &pt_decode_unknown);
116
117	return ptu_passed();
118}
119
120static struct ptunit_result fetch_unknown_ext(struct fetch_fixture *ffix)
121{
122	const struct pt_decoder_function *dfun;
123	int errcode;
124
125	ffix->config.begin[0] = pt_opc_ext;
126	ffix->config.begin[1] = pt_ext_bad;
127
128	errcode = pt_df_fetch(&dfun, ffix->config.begin, &ffix->config);
129	ptu_int_eq(errcode, 0);
130	ptu_ptr_eq(dfun, &pt_decode_unknown);
131
132	return ptu_passed();
133}
134
135static struct ptunit_result fetch_unknown_ext2(struct fetch_fixture *ffix)
136{
137	const struct pt_decoder_function *dfun;
138	int errcode;
139
140	ffix->config.begin[0] = pt_opc_ext;
141	ffix->config.begin[1] = pt_ext_ext2;
142	ffix->config.begin[2] = pt_ext2_bad;
143
144	errcode = pt_df_fetch(&dfun, ffix->config.begin, &ffix->config);
145	ptu_int_eq(errcode, 0);
146	ptu_ptr_eq(dfun, &pt_decode_unknown);
147
148	return ptu_passed();
149}
150
151static struct ptunit_result fetch_packet(struct fetch_fixture *ffix,
152					 const struct pt_packet *packet,
153					 const struct pt_decoder_function *df)
154{
155	const struct pt_decoder_function *dfun;
156	int errcode;
157
158	errcode = pt_enc_next(&ffix->encoder, packet);
159	ptu_int_ge(errcode, 0);
160
161	errcode = pt_df_fetch(&dfun, ffix->config.begin, &ffix->config);
162	ptu_int_eq(errcode, 0);
163	ptu_ptr_eq(dfun, df);
164
165	return ptu_passed();
166}
167
168static struct ptunit_result fetch_type(struct fetch_fixture *ffix,
169				       enum pt_packet_type type,
170				       const struct pt_decoder_function *dfun)
171{
172	struct pt_packet packet;
173
174	memset(&packet, 0, sizeof(packet));
175	packet.type = type;
176
177	ptu_test(fetch_packet, ffix, &packet, dfun);
178
179	return ptu_passed();
180}
181
182static struct ptunit_result fetch_tnt_8(struct fetch_fixture *ffix)
183{
184	struct pt_packet packet;
185
186	memset(&packet, 0, sizeof(packet));
187	packet.type = ppt_tnt_8;
188	packet.payload.tnt.bit_size = 1;
189
190	ptu_test(fetch_packet, ffix, &packet, &pt_decode_tnt_8);
191
192	return ptu_passed();
193}
194
195static struct ptunit_result fetch_mode_exec(struct fetch_fixture *ffix)
196{
197	struct pt_packet packet;
198
199	memset(&packet, 0, sizeof(packet));
200	packet.type = ppt_mode;
201	packet.payload.mode.leaf = pt_mol_exec;
202
203	ptu_test(fetch_packet, ffix, &packet, &pt_decode_mode);
204
205	return ptu_passed();
206}
207
208static struct ptunit_result fetch_mode_tsx(struct fetch_fixture *ffix)
209{
210	struct pt_packet packet;
211
212	memset(&packet, 0, sizeof(packet));
213	packet.type = ppt_mode;
214	packet.payload.mode.leaf = pt_mol_tsx;
215
216	ptu_test(fetch_packet, ffix, &packet, &pt_decode_mode);
217
218	return ptu_passed();
219}
220
221static struct ptunit_result fetch_exstop_ip(struct fetch_fixture *ffix)
222{
223	struct pt_packet packet;
224
225	memset(&packet, 0, sizeof(packet));
226	packet.type = ppt_exstop;
227	packet.payload.exstop.ip = 1;
228
229	ptu_test(fetch_packet, ffix, &packet, &pt_decode_exstop);
230
231	return ptu_passed();
232}
233
234int main(int argc, char **argv)
235{
236	struct fetch_fixture ffix;
237	struct ptunit_suite suite;
238
239	ffix.init = ffix_init;
240	ffix.fini = ffix_fini;
241
242	suite = ptunit_mk_suite(argc, argv);
243
244	ptu_run_f(suite, fetch_null, ffix);
245	ptu_run_f(suite, fetch_empty, ffix);
246
247	ptu_run_f(suite, fetch_unknown, ffix);
248	ptu_run_f(suite, fetch_unknown_ext, ffix);
249	ptu_run_f(suite, fetch_unknown_ext2, ffix);
250
251	ptu_run_fp(suite, fetch_type, ffix, ppt_pad, &pt_decode_pad);
252	ptu_run_fp(suite, fetch_type, ffix, ppt_psb, &pt_decode_psb);
253	ptu_run_fp(suite, fetch_type, ffix, ppt_tip, &pt_decode_tip);
254	ptu_run_fp(suite, fetch_type, ffix, ppt_tnt_64, &pt_decode_tnt_64);
255	ptu_run_fp(suite, fetch_type, ffix, ppt_tip_pge, &pt_decode_tip_pge);
256	ptu_run_fp(suite, fetch_type, ffix, ppt_tip_pgd, &pt_decode_tip_pgd);
257	ptu_run_fp(suite, fetch_type, ffix, ppt_fup, &pt_decode_fup);
258	ptu_run_fp(suite, fetch_type, ffix, ppt_pip, &pt_decode_pip);
259	ptu_run_fp(suite, fetch_type, ffix, ppt_ovf, &pt_decode_ovf);
260	ptu_run_fp(suite, fetch_type, ffix, ppt_psbend, &pt_decode_psbend);
261	ptu_run_fp(suite, fetch_type, ffix, ppt_tsc, &pt_decode_tsc);
262	ptu_run_fp(suite, fetch_type, ffix, ppt_cbr, &pt_decode_cbr);
263	ptu_run_fp(suite, fetch_type, ffix, ppt_tma, &pt_decode_tma);
264	ptu_run_fp(suite, fetch_type, ffix, ppt_mtc, &pt_decode_mtc);
265	ptu_run_fp(suite, fetch_type, ffix, ppt_cyc, &pt_decode_cyc);
266	ptu_run_fp(suite, fetch_type, ffix, ppt_stop, &pt_decode_stop);
267	ptu_run_fp(suite, fetch_type, ffix, ppt_vmcs, &pt_decode_vmcs);
268	ptu_run_fp(suite, fetch_type, ffix, ppt_mnt, &pt_decode_mnt);
269	ptu_run_fp(suite, fetch_type, ffix, ppt_exstop, &pt_decode_exstop);
270	ptu_run_fp(suite, fetch_type, ffix, ppt_mwait, &pt_decode_mwait);
271	ptu_run_fp(suite, fetch_type, ffix, ppt_pwre, &pt_decode_pwre);
272	ptu_run_fp(suite, fetch_type, ffix, ppt_pwrx, &pt_decode_pwrx);
273	ptu_run_fp(suite, fetch_type, ffix, ppt_ptw, &pt_decode_ptw);
274
275	ptu_run_f(suite, fetch_tnt_8, ffix);
276	ptu_run_f(suite, fetch_mode_exec, ffix);
277	ptu_run_f(suite, fetch_mode_tsx, ffix);
278	ptu_run_f(suite, fetch_exstop_ip, ffix);
279
280	return ptunit_report(&suite);
281}
282
283
284/* Dummy decode functions to satisfy link dependencies.
285 *
286 * As a nice side-effect, we will know if we need to add more tests when
287 * adding new decoder functions.
288 */
289int pt_pkt_decode_unknown(struct pt_packet_decoder *d, struct pt_packet *p)
290{
291	(void) d;
292	(void) p;
293
294	return -pte_internal;
295}
296int pt_qry_decode_unknown(struct pt_query_decoder *d)
297{
298	(void) d;
299
300	return -pte_internal;
301}
302
303int pt_pkt_decode_pad(struct pt_packet_decoder *d, struct pt_packet *p)
304{
305	(void) d;
306	(void) p;
307
308	return -pte_internal;
309}
310int pt_qry_decode_pad(struct pt_query_decoder *d)
311{
312	(void) d;
313
314	return -pte_internal;
315}
316
317int pt_pkt_decode_psb(struct pt_packet_decoder *d, struct pt_packet *p)
318{
319	(void) d;
320	(void) p;
321
322	return -pte_internal;
323}
324int pt_qry_decode_psb(struct pt_query_decoder *d)
325{
326	(void) d;
327
328	return -pte_internal;
329}
330
331int pt_pkt_decode_tip(struct pt_packet_decoder *d, struct pt_packet *p)
332{
333	(void) d;
334	(void) p;
335
336	return -pte_internal;
337}
338int pt_qry_decode_tip(struct pt_query_decoder *d)
339{
340	(void) d;
341
342	return -pte_internal;
343}
344
345int pt_pkt_decode_tnt_8(struct pt_packet_decoder *d, struct pt_packet *p)
346{
347	(void) d;
348	(void) p;
349
350	return -pte_internal;
351}
352int pt_qry_decode_tnt_8(struct pt_query_decoder *d)
353{
354	(void) d;
355
356	return -pte_internal;
357}
358
359int pt_pkt_decode_tnt_64(struct pt_packet_decoder *d, struct pt_packet *p)
360{
361	(void) d;
362	(void) p;
363
364	return -pte_internal;
365}
366int pt_qry_decode_tnt_64(struct pt_query_decoder *d)
367{
368	(void) d;
369
370	return -pte_internal;
371}
372
373int pt_pkt_decode_tip_pge(struct pt_packet_decoder *d, struct pt_packet *p)
374{
375	(void) d;
376	(void) p;
377
378	return -pte_internal;
379}
380int pt_qry_decode_tip_pge(struct pt_query_decoder *d)
381{
382	(void) d;
383
384	return -pte_internal;
385}
386
387int pt_pkt_decode_tip_pgd(struct pt_packet_decoder *d, struct pt_packet *p)
388{
389	(void) d;
390	(void) p;
391
392	return -pte_internal;
393}
394int pt_qry_decode_tip_pgd(struct pt_query_decoder *d)
395{
396	(void) d;
397
398	return -pte_internal;
399}
400
401int pt_pkt_decode_fup(struct pt_packet_decoder *d, struct pt_packet *p)
402{
403	(void) d;
404	(void) p;
405
406	return -pte_internal;
407}
408int pt_qry_decode_fup(struct pt_query_decoder *d)
409{
410	(void) d;
411
412	return -pte_internal;
413}
414int pt_qry_header_fup(struct pt_query_decoder *d)
415{
416	(void) d;
417
418	return -pte_internal;
419}
420
421int pt_pkt_decode_pip(struct pt_packet_decoder *d, struct pt_packet *p)
422{
423	(void) d;
424	(void) p;
425
426	return -pte_internal;
427}
428int pt_qry_decode_pip(struct pt_query_decoder *d)
429{
430	(void) d;
431
432	return -pte_internal;
433}
434int pt_qry_header_pip(struct pt_query_decoder *d)
435{
436	(void) d;
437
438	return -pte_internal;
439}
440
441int pt_pkt_decode_ovf(struct pt_packet_decoder *d, struct pt_packet *p)
442{
443	(void) d;
444	(void) p;
445
446	return -pte_internal;
447}
448int pt_qry_decode_ovf(struct pt_query_decoder *d)
449{
450	(void) d;
451
452	return -pte_internal;
453}
454
455int pt_pkt_decode_mode(struct pt_packet_decoder *d, struct pt_packet *p)
456{
457	(void) d;
458	(void) p;
459
460	return -pte_internal;
461}
462int pt_qry_decode_mode(struct pt_query_decoder *d)
463{
464	(void) d;
465
466	return -pte_internal;
467}
468int pt_qry_header_mode(struct pt_query_decoder *d)
469{
470	(void) d;
471
472	return -pte_internal;
473}
474
475int pt_pkt_decode_psbend(struct pt_packet_decoder *d, struct pt_packet *p)
476{
477	(void) d;
478	(void) p;
479
480	return -pte_internal;
481}
482int pt_qry_decode_psbend(struct pt_query_decoder *d)
483{
484	(void) d;
485
486	return -pte_internal;
487}
488
489int pt_pkt_decode_tsc(struct pt_packet_decoder *d, struct pt_packet *p)
490{
491	(void) d;
492	(void) p;
493
494	return -pte_internal;
495}
496int pt_qry_decode_tsc(struct pt_query_decoder *d)
497{
498	(void) d;
499
500	return -pte_internal;
501}
502int pt_qry_header_tsc(struct pt_query_decoder *d)
503{
504	(void) d;
505
506	return -pte_internal;
507}
508
509int pt_pkt_decode_cbr(struct pt_packet_decoder *d, struct pt_packet *p)
510{
511	(void) d;
512	(void) p;
513
514	return -pte_internal;
515}
516int pt_qry_decode_cbr(struct pt_query_decoder *d)
517{
518	(void) d;
519
520	return -pte_internal;
521}
522int pt_qry_header_cbr(struct pt_query_decoder *d)
523{
524	(void) d;
525
526	return -pte_internal;
527}
528
529int pt_pkt_decode_tma(struct pt_packet_decoder *d, struct pt_packet *p)
530{
531	(void) d;
532	(void) p;
533
534	return -pte_internal;
535}
536int pt_qry_decode_tma(struct pt_query_decoder *d)
537{
538	(void) d;
539
540	return -pte_internal;
541}
542
543int pt_pkt_decode_mtc(struct pt_packet_decoder *d, struct pt_packet *p)
544{
545	(void) d;
546	(void) p;
547
548	return -pte_internal;
549}
550int pt_qry_decode_mtc(struct pt_query_decoder *d)
551{
552	(void) d;
553
554	return -pte_internal;
555}
556
557int pt_pkt_decode_cyc(struct pt_packet_decoder *d, struct pt_packet *p)
558{
559	(void) d;
560	(void) p;
561
562	return -pte_internal;
563}
564int pt_qry_decode_cyc(struct pt_query_decoder *d)
565{
566	(void) d;
567
568	return -pte_internal;
569}
570
571int pt_pkt_decode_stop(struct pt_packet_decoder *d, struct pt_packet *p)
572{
573	(void) d;
574	(void) p;
575
576	return -pte_internal;
577}
578int pt_qry_decode_stop(struct pt_query_decoder *d)
579{
580	(void) d;
581
582	return -pte_internal;
583}
584
585int pt_pkt_decode_vmcs(struct pt_packet_decoder *d, struct pt_packet *p)
586{
587	(void) d;
588	(void) p;
589
590	return -pte_internal;
591}
592int pt_qry_decode_vmcs(struct pt_query_decoder *d)
593{
594	(void) d;
595
596	return -pte_internal;
597}
598int pt_qry_header_vmcs(struct pt_query_decoder *d)
599{
600	(void) d;
601
602	return -pte_internal;
603}
604
605int pt_pkt_decode_mnt(struct pt_packet_decoder *d, struct pt_packet *p)
606{
607	(void) d;
608	(void) p;
609
610	return -pte_internal;
611}
612int pt_qry_decode_mnt(struct pt_query_decoder *d)
613{
614	(void) d;
615
616	return -pte_internal;
617}
618int pt_qry_header_mnt(struct pt_query_decoder *d)
619{
620	(void) d;
621
622	return -pte_internal;
623}
624
625int pt_pkt_decode_exstop(struct pt_packet_decoder *d, struct pt_packet *p)
626{
627	(void) d;
628	(void) p;
629
630	return -pte_internal;
631}
632int pt_qry_decode_exstop(struct pt_query_decoder *d)
633{
634	(void) d;
635
636	return -pte_internal;
637}
638
639int pt_pkt_decode_mwait(struct pt_packet_decoder *d, struct pt_packet *p)
640{
641	(void) d;
642	(void) p;
643
644	return -pte_internal;
645}
646int pt_qry_decode_mwait(struct pt_query_decoder *d)
647{
648	(void) d;
649
650	return -pte_internal;
651}
652
653int pt_pkt_decode_pwre(struct pt_packet_decoder *d, struct pt_packet *p)
654{
655	(void) d;
656	(void) p;
657
658	return -pte_internal;
659}
660int pt_qry_decode_pwre(struct pt_query_decoder *d)
661{
662	(void) d;
663
664	return -pte_internal;
665}
666
667int pt_pkt_decode_pwrx(struct pt_packet_decoder *d, struct pt_packet *p)
668{
669	(void) d;
670	(void) p;
671
672	return -pte_internal;
673}
674int pt_qry_decode_pwrx(struct pt_query_decoder *d)
675{
676	(void) d;
677
678	return -pte_internal;
679}
680
681int pt_pkt_decode_ptw(struct pt_packet_decoder *d, struct pt_packet *p)
682{
683	(void) d;
684	(void) p;
685
686	return -pte_internal;
687}
688int pt_qry_decode_ptw(struct pt_query_decoder *d)
689{
690	(void) d;
691
692	return -pte_internal;
693}
694