xref: /freebsd/contrib/processor-trace/libipt/src/pt_packet_decoder.c (revision 5ca8e32633c4ffbbcd6762e5888b6a4ba0708c6c)
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 "pt_packet_decoder.h"
30 #include "pt_decoder_function.h"
31 #include "pt_packet.h"
32 #include "pt_sync.h"
33 #include "pt_config.h"
34 #include "pt_opcodes.h"
35 
36 #include <string.h>
37 #include <stdlib.h>
38 #include <stddef.h>
39 
40 
41 int pt_pkt_decoder_init(struct pt_packet_decoder *decoder,
42 			const struct pt_config *config)
43 {
44 	int errcode;
45 
46 	if (!decoder || !config)
47 		return -pte_invalid;
48 
49 	memset(decoder, 0, sizeof(*decoder));
50 
51 	errcode = pt_config_from_user(&decoder->config, config);
52 	if (errcode < 0)
53 		return errcode;
54 
55 	return 0;
56 }
57 
58 struct pt_packet_decoder *pt_pkt_alloc_decoder(const struct pt_config *config)
59 {
60 	struct pt_packet_decoder *decoder;
61 	int errcode;
62 
63 	decoder = malloc(sizeof(*decoder));
64 	if (!decoder)
65 		return NULL;
66 
67 	errcode = pt_pkt_decoder_init(decoder, config);
68 	if (errcode < 0) {
69 		free(decoder);
70 		return NULL;
71 	}
72 
73 	return decoder;
74 }
75 
76 void pt_pkt_decoder_fini(struct pt_packet_decoder *decoder)
77 {
78 	(void) decoder;
79 
80 	/* Nothing to do. */
81 }
82 
83 void pt_pkt_free_decoder(struct pt_packet_decoder *decoder)
84 {
85 	pt_pkt_decoder_fini(decoder);
86 	free(decoder);
87 }
88 
89 int pt_pkt_sync_forward(struct pt_packet_decoder *decoder)
90 {
91 	const uint8_t *pos, *sync, *begin;
92 	ptrdiff_t space;
93 	int errcode;
94 
95 	if (!decoder)
96 		return -pte_invalid;
97 
98 	begin = decoder->config.begin;
99 	sync = decoder->sync;
100 	pos = decoder->pos;
101 	if (!pos)
102 		pos = begin;
103 
104 	if (pos == sync)
105 		pos += ptps_psb;
106 
107 	if (pos < begin)
108 		return -pte_internal;
109 
110 	/* Start a bit earlier so we find PSB that have been partially consumed
111 	 * by a preceding packet.
112 	 */
113 	space = pos - begin;
114 	if (ptps_psb <= space)
115 		space = ptps_psb - 1;
116 
117 	pos -= space;
118 
119 	errcode = pt_sync_forward(&sync, pos, &decoder->config);
120 	if (errcode < 0)
121 		return errcode;
122 
123 	decoder->sync = sync;
124 	decoder->pos = sync;
125 
126 	return 0;
127 }
128 
129 int pt_pkt_sync_backward(struct pt_packet_decoder *decoder)
130 {
131 	const uint8_t *pos, *sync;
132 	int errcode;
133 
134 	if (!decoder)
135 		return -pte_invalid;
136 
137 	pos = decoder->pos;
138 	if (!pos)
139 		pos = decoder->config.end;
140 
141 	errcode = pt_sync_backward(&sync, pos, &decoder->config);
142 	if (errcode < 0)
143 		return errcode;
144 
145 	decoder->sync = sync;
146 	decoder->pos = sync;
147 
148 	return 0;
149 }
150 
151 int pt_pkt_sync_set(struct pt_packet_decoder *decoder, uint64_t offset)
152 {
153 	const uint8_t *begin, *end, *pos;
154 
155 	if (!decoder)
156 		return -pte_invalid;
157 
158 	begin = decoder->config.begin;
159 	end = decoder->config.end;
160 	pos = begin + offset;
161 
162 	if (end < pos || pos < begin)
163 		return -pte_eos;
164 
165 	decoder->sync = pos;
166 	decoder->pos = pos;
167 
168 	return 0;
169 }
170 
171 int pt_pkt_get_offset(const struct pt_packet_decoder *decoder, uint64_t *offset)
172 {
173 	const uint8_t *begin, *pos;
174 
175 	if (!decoder || !offset)
176 		return -pte_invalid;
177 
178 	begin = decoder->config.begin;
179 	pos = decoder->pos;
180 
181 	if (!pos)
182 		return -pte_nosync;
183 
184 	*offset = (uint64_t) (int64_t) (pos - begin);
185 	return 0;
186 }
187 
188 int pt_pkt_get_sync_offset(const struct pt_packet_decoder *decoder,
189 			   uint64_t *offset)
190 {
191 	const uint8_t *begin, *sync;
192 
193 	if (!decoder || !offset)
194 		return -pte_invalid;
195 
196 	begin = decoder->config.begin;
197 	sync = decoder->sync;
198 
199 	if (!sync)
200 		return -pte_nosync;
201 
202 	*offset = (uint64_t) (int64_t) (sync - begin);
203 	return 0;
204 }
205 
206 const struct pt_config *
207 pt_pkt_get_config(const struct pt_packet_decoder *decoder)
208 {
209 	if (!decoder)
210 		return NULL;
211 
212 	return &decoder->config;
213 }
214 
215 static inline int pkt_to_user(struct pt_packet *upkt, size_t size,
216 			      const struct pt_packet *pkt)
217 {
218 	if (!upkt || !pkt)
219 		return -pte_internal;
220 
221 	if (upkt == pkt)
222 		return 0;
223 
224 	/* Zero out any unknown bytes. */
225 	if (sizeof(*pkt) < size) {
226 		memset(upkt + sizeof(*pkt), 0, size - sizeof(*pkt));
227 
228 		size = sizeof(*pkt);
229 	}
230 
231 	memcpy(upkt, pkt, size);
232 
233 	return 0;
234 }
235 
236 int pt_pkt_next(struct pt_packet_decoder *decoder, struct pt_packet *packet,
237 		size_t psize)
238 {
239 	const struct pt_decoder_function *dfun;
240 	struct pt_packet pkt, *ppkt;
241 	int errcode, size;
242 
243 	if (!packet || !decoder)
244 		return -pte_invalid;
245 
246 	ppkt = psize == sizeof(pkt) ? packet : &pkt;
247 
248 	errcode = pt_df_fetch(&dfun, decoder->pos, &decoder->config);
249 	if (errcode < 0)
250 		return errcode;
251 
252 	if (!dfun)
253 		return -pte_internal;
254 
255 	if (!dfun->packet)
256 		return -pte_internal;
257 
258 	size = dfun->packet(decoder, ppkt);
259 	if (size < 0)
260 		return size;
261 
262 	errcode = pkt_to_user(packet, psize, ppkt);
263 	if (errcode < 0)
264 		return errcode;
265 
266 	decoder->pos += size;
267 
268 	return size;
269 }
270 
271 int pt_pkt_decode_unknown(struct pt_packet_decoder *decoder,
272 			  struct pt_packet *packet)
273 {
274 	int size;
275 
276 	if (!decoder)
277 		return -pte_internal;
278 
279 	size = pt_pkt_read_unknown(packet, decoder->pos, &decoder->config);
280 	if (size < 0)
281 		return size;
282 
283 	return size;
284 }
285 
286 int pt_pkt_decode_pad(struct pt_packet_decoder *decoder,
287 		      struct pt_packet *packet)
288 {
289 	(void) decoder;
290 
291 	if (!packet)
292 		return -pte_internal;
293 
294 	packet->type = ppt_pad;
295 	packet->size = ptps_pad;
296 
297 	return ptps_pad;
298 }
299 
300 int pt_pkt_decode_psb(struct pt_packet_decoder *decoder,
301 		      struct pt_packet *packet)
302 {
303 	int size;
304 
305 	if (!decoder)
306 		return -pte_internal;
307 
308 	size = pt_pkt_read_psb(decoder->pos, &decoder->config);
309 	if (size < 0)
310 		return size;
311 
312 	packet->type = ppt_psb;
313 	packet->size = (uint8_t) size;
314 
315 	return size;
316 }
317 
318 int pt_pkt_decode_tip(struct pt_packet_decoder *decoder,
319 		      struct pt_packet *packet)
320 {
321 	int size;
322 
323 	if (!decoder || !packet)
324 		return -pte_internal;
325 
326 	size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
327 			      &decoder->config);
328 	if (size < 0)
329 		return size;
330 
331 	packet->type = ppt_tip;
332 	packet->size = (uint8_t) size;
333 
334 	return size;
335 }
336 
337 int pt_pkt_decode_tnt_8(struct pt_packet_decoder *decoder,
338 			struct pt_packet *packet)
339 {
340 	int size;
341 
342 	if (!decoder || !packet)
343 		return -pte_internal;
344 
345 	size = pt_pkt_read_tnt_8(&packet->payload.tnt, decoder->pos,
346 				 &decoder->config);
347 	if (size < 0)
348 		return size;
349 
350 	packet->type = ppt_tnt_8;
351 	packet->size = (uint8_t) size;
352 
353 	return size;
354 }
355 
356 int pt_pkt_decode_tnt_64(struct pt_packet_decoder *decoder,
357 			 struct pt_packet *packet)
358 {
359 	int size;
360 
361 	if (!decoder || !packet)
362 		return -pte_internal;
363 
364 	size = pt_pkt_read_tnt_64(&packet->payload.tnt, decoder->pos,
365 				  &decoder->config);
366 	if (size < 0)
367 		return size;
368 
369 	packet->type = ppt_tnt_64;
370 	packet->size = (uint8_t) size;
371 
372 	return size;
373 }
374 
375 int pt_pkt_decode_tip_pge(struct pt_packet_decoder *decoder,
376 			  struct pt_packet *packet)
377 {
378 	int size;
379 
380 	if (!decoder || !packet)
381 		return -pte_internal;
382 
383 	size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
384 			      &decoder->config);
385 	if (size < 0)
386 		return size;
387 
388 	packet->type = ppt_tip_pge;
389 	packet->size = (uint8_t) size;
390 
391 	return size;
392 }
393 
394 int pt_pkt_decode_tip_pgd(struct pt_packet_decoder *decoder,
395 			  struct pt_packet *packet)
396 {
397 	int size;
398 
399 	if (!decoder || !packet)
400 		return -pte_internal;
401 
402 	size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
403 			      &decoder->config);
404 	if (size < 0)
405 		return size;
406 
407 	packet->type = ppt_tip_pgd;
408 	packet->size = (uint8_t) size;
409 
410 	return size;
411 }
412 
413 int pt_pkt_decode_fup(struct pt_packet_decoder *decoder,
414 		      struct pt_packet *packet)
415 {
416 	int size;
417 
418 	if (!decoder || !packet)
419 		return -pte_internal;
420 
421 	size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
422 			      &decoder->config);
423 	if (size < 0)
424 		return size;
425 
426 	packet->type = ppt_fup;
427 	packet->size = (uint8_t) size;
428 
429 	return size;
430 }
431 
432 int pt_pkt_decode_pip(struct pt_packet_decoder *decoder,
433 		      struct pt_packet *packet)
434 {
435 	int size;
436 
437 	if (!decoder || !packet)
438 		return -pte_internal;
439 
440 	size = pt_pkt_read_pip(&packet->payload.pip, decoder->pos,
441 			       &decoder->config);
442 	if (size < 0)
443 		return size;
444 
445 	packet->type = ppt_pip;
446 	packet->size = (uint8_t) size;
447 
448 	return size;
449 }
450 
451 int pt_pkt_decode_ovf(struct pt_packet_decoder *decoder,
452 		      struct pt_packet *packet)
453 {
454 	(void) decoder;
455 
456 	if (!packet)
457 		return -pte_internal;
458 
459 	packet->type = ppt_ovf;
460 	packet->size = ptps_ovf;
461 
462 	return ptps_ovf;
463 }
464 
465 int pt_pkt_decode_mode(struct pt_packet_decoder *decoder,
466 		       struct pt_packet *packet)
467 {
468 	int size;
469 
470 	if (!decoder || !packet)
471 		return -pte_internal;
472 
473 	size = pt_pkt_read_mode(&packet->payload.mode, decoder->pos,
474 				&decoder->config);
475 	if (size < 0)
476 		return size;
477 
478 	packet->type = ppt_mode;
479 	packet->size = (uint8_t) size;
480 
481 	return size;
482 }
483 
484 int pt_pkt_decode_psbend(struct pt_packet_decoder *decoder,
485 			 struct pt_packet *packet)
486 {
487 	(void) decoder;
488 
489 	if (!packet)
490 		return -pte_internal;
491 
492 	packet->type = ppt_psbend;
493 	packet->size = ptps_psbend;
494 
495 	return ptps_psbend;
496 }
497 
498 int pt_pkt_decode_tsc(struct pt_packet_decoder *decoder,
499 		      struct pt_packet *packet)
500 {
501 	int size;
502 
503 	if (!decoder || !packet)
504 		return -pte_internal;
505 
506 	size = pt_pkt_read_tsc(&packet->payload.tsc, decoder->pos,
507 			       &decoder->config);
508 	if (size < 0)
509 		return size;
510 
511 	packet->type = ppt_tsc;
512 	packet->size = (uint8_t) size;
513 
514 	return size;
515 }
516 
517 int pt_pkt_decode_cbr(struct pt_packet_decoder *decoder,
518 		      struct pt_packet *packet)
519 {
520 	int size;
521 
522 	if (!decoder || !packet)
523 		return -pte_internal;
524 
525 	size = pt_pkt_read_cbr(&packet->payload.cbr, decoder->pos,
526 			       &decoder->config);
527 	if (size < 0)
528 		return size;
529 
530 	packet->type = ppt_cbr;
531 	packet->size = (uint8_t) size;
532 
533 	return size;
534 }
535 
536 int pt_pkt_decode_tma(struct pt_packet_decoder *decoder,
537 		      struct pt_packet *packet)
538 {
539 	int size;
540 
541 	if (!decoder || !packet)
542 		return -pte_internal;
543 
544 	size = pt_pkt_read_tma(&packet->payload.tma, decoder->pos,
545 			       &decoder->config);
546 	if (size < 0)
547 		return size;
548 
549 	packet->type = ppt_tma;
550 	packet->size = (uint8_t) size;
551 
552 	return size;
553 }
554 
555 int pt_pkt_decode_mtc(struct pt_packet_decoder *decoder,
556 		      struct pt_packet *packet)
557 {
558 	int size;
559 
560 	if (!decoder || !packet)
561 		return -pte_internal;
562 
563 	size = pt_pkt_read_mtc(&packet->payload.mtc, decoder->pos,
564 			       &decoder->config);
565 	if (size < 0)
566 		return size;
567 
568 	packet->type = ppt_mtc;
569 	packet->size = (uint8_t) size;
570 
571 	return size;
572 }
573 
574 int pt_pkt_decode_cyc(struct pt_packet_decoder *decoder,
575 		      struct pt_packet *packet)
576 {
577 	int size;
578 
579 	if (!decoder || !packet)
580 		return -pte_internal;
581 
582 	size = pt_pkt_read_cyc(&packet->payload.cyc, decoder->pos,
583 			       &decoder->config);
584 	if (size < 0)
585 		return size;
586 
587 	packet->type = ppt_cyc;
588 	packet->size = (uint8_t) size;
589 
590 	return size;
591 }
592 
593 int pt_pkt_decode_stop(struct pt_packet_decoder *decoder,
594 		       struct pt_packet *packet)
595 {
596 	(void) decoder;
597 
598 	if (!packet)
599 		return -pte_internal;
600 
601 	packet->type = ppt_stop;
602 	packet->size = ptps_stop;
603 
604 	return ptps_stop;
605 }
606 
607 int pt_pkt_decode_vmcs(struct pt_packet_decoder *decoder,
608 		       struct pt_packet *packet)
609 {
610 	int size;
611 
612 	if (!decoder || !packet)
613 		return -pte_internal;
614 
615 	size = pt_pkt_read_vmcs(&packet->payload.vmcs, decoder->pos,
616 			       &decoder->config);
617 	if (size < 0)
618 		return size;
619 
620 	packet->type = ppt_vmcs;
621 	packet->size = (uint8_t) size;
622 
623 	return size;
624 }
625 
626 int pt_pkt_decode_mnt(struct pt_packet_decoder *decoder,
627 		      struct pt_packet *packet)
628 {
629 	int size;
630 
631 	if (!decoder || !packet)
632 		return -pte_internal;
633 
634 	size = pt_pkt_read_mnt(&packet->payload.mnt, decoder->pos,
635 			       &decoder->config);
636 	if (size < 0)
637 		return size;
638 
639 	packet->type = ppt_mnt;
640 	packet->size = (uint8_t) size;
641 
642 	return size;
643 }
644 
645 int pt_pkt_decode_exstop(struct pt_packet_decoder *decoder,
646 			 struct pt_packet *packet)
647 {
648 	int size;
649 
650 	if (!decoder || !packet)
651 		return -pte_internal;
652 
653 	size = pt_pkt_read_exstop(&packet->payload.exstop, decoder->pos,
654 				  &decoder->config);
655 	if (size < 0)
656 		return size;
657 
658 	packet->type = ppt_exstop;
659 	packet->size = (uint8_t) size;
660 
661 	return size;
662 }
663 
664 int pt_pkt_decode_mwait(struct pt_packet_decoder *decoder,
665 			struct pt_packet *packet)
666 {
667 	int size;
668 
669 	if (!decoder || !packet)
670 		return -pte_internal;
671 
672 	size = pt_pkt_read_mwait(&packet->payload.mwait, decoder->pos,
673 				 &decoder->config);
674 	if (size < 0)
675 		return size;
676 
677 	packet->type = ppt_mwait;
678 	packet->size = (uint8_t) size;
679 
680 	return size;
681 }
682 
683 int pt_pkt_decode_pwre(struct pt_packet_decoder *decoder,
684 		       struct pt_packet *packet)
685 {
686 	int size;
687 
688 	if (!decoder || !packet)
689 		return -pte_internal;
690 
691 	size = pt_pkt_read_pwre(&packet->payload.pwre, decoder->pos,
692 				&decoder->config);
693 	if (size < 0)
694 		return size;
695 
696 	packet->type = ppt_pwre;
697 	packet->size = (uint8_t) size;
698 
699 	return size;
700 }
701 
702 int pt_pkt_decode_pwrx(struct pt_packet_decoder *decoder,
703 		       struct pt_packet *packet)
704 {
705 	int size;
706 
707 	if (!decoder || !packet)
708 		return -pte_internal;
709 
710 	size = pt_pkt_read_pwrx(&packet->payload.pwrx, decoder->pos,
711 				&decoder->config);
712 	if (size < 0)
713 		return size;
714 
715 	packet->type = ppt_pwrx;
716 	packet->size = (uint8_t) size;
717 
718 	return size;
719 }
720 
721 int pt_pkt_decode_ptw(struct pt_packet_decoder *decoder,
722 		      struct pt_packet *packet)
723 {
724 	int size;
725 
726 	if (!decoder || !packet)
727 		return -pte_internal;
728 
729 	size = pt_pkt_read_ptw(&packet->payload.ptw, decoder->pos,
730 			       &decoder->config);
731 	if (size < 0)
732 		return size;
733 
734 	packet->type = ppt_ptw;
735 	packet->size = (uint8_t) size;
736 
737 	return size;
738 }
739