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