2 * Copyright (c) 2014-2018, Intel Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
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.
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.
29 #include "pt_packet_decoder.h"
30 #include "pt_decoder_function.h"
31 #include "pt_packet.h"
33 #include "pt_config.h"
34 #include "pt_opcodes.h"
40 int pt_pkt_decoder_init(struct pt_packet_decoder *decoder,
41 const struct pt_config *config)
45 if (!decoder || !config)
48 memset(decoder, 0, sizeof(*decoder));
50 errcode = pt_config_from_user(&decoder->config, config);
57 struct pt_packet_decoder *pt_pkt_alloc_decoder(const struct pt_config *config)
59 struct pt_packet_decoder *decoder;
62 decoder = malloc(sizeof(*decoder));
66 errcode = pt_pkt_decoder_init(decoder, config);
75 void pt_pkt_decoder_fini(struct pt_packet_decoder *decoder)
82 void pt_pkt_free_decoder(struct pt_packet_decoder *decoder)
84 pt_pkt_decoder_fini(decoder);
88 int pt_pkt_sync_forward(struct pt_packet_decoder *decoder)
90 const uint8_t *pos, *sync;
99 pos = decoder->config.begin;
104 errcode = pt_sync_forward(&sync, pos, &decoder->config);
108 decoder->sync = sync;
114 int pt_pkt_sync_backward(struct pt_packet_decoder *decoder)
116 const uint8_t *pos, *sync;
124 pos = decoder->config.end;
126 errcode = pt_sync_backward(&sync, pos, &decoder->config);
130 decoder->sync = sync;
136 int pt_pkt_sync_set(struct pt_packet_decoder *decoder, uint64_t offset)
138 const uint8_t *begin, *end, *pos;
143 begin = decoder->config.begin;
144 end = decoder->config.end;
145 pos = begin + offset;
147 if (end < pos || pos < begin)
156 int pt_pkt_get_offset(const struct pt_packet_decoder *decoder, uint64_t *offset)
158 const uint8_t *begin, *pos;
160 if (!decoder || !offset)
163 begin = decoder->config.begin;
169 *offset = pos - begin;
173 int pt_pkt_get_sync_offset(const struct pt_packet_decoder *decoder,
176 const uint8_t *begin, *sync;
178 if (!decoder || !offset)
181 begin = decoder->config.begin;
182 sync = decoder->sync;
187 *offset = sync - begin;
191 const struct pt_config *
192 pt_pkt_get_config(const struct pt_packet_decoder *decoder)
197 return &decoder->config;
200 static inline int pkt_to_user(struct pt_packet *upkt, size_t size,
201 const struct pt_packet *pkt)
204 return -pte_internal;
209 /* Zero out any unknown bytes. */
210 if (sizeof(*pkt) < size) {
211 memset(upkt + sizeof(*pkt), 0, size - sizeof(*pkt));
216 memcpy(upkt, pkt, size);
221 int pt_pkt_next(struct pt_packet_decoder *decoder, struct pt_packet *packet,
224 const struct pt_decoder_function *dfun;
225 struct pt_packet pkt, *ppkt;
228 if (!packet || !decoder)
231 ppkt = psize == sizeof(pkt) ? packet : &pkt;
233 errcode = pt_df_fetch(&dfun, decoder->pos, &decoder->config);
238 return -pte_internal;
241 return -pte_internal;
243 size = dfun->packet(decoder, ppkt);
247 errcode = pkt_to_user(packet, psize, ppkt);
251 decoder->pos += size;
256 int pt_pkt_decode_unknown(struct pt_packet_decoder *decoder,
257 struct pt_packet *packet)
262 return -pte_internal;
264 size = pt_pkt_read_unknown(packet, decoder->pos, &decoder->config);
271 int pt_pkt_decode_pad(struct pt_packet_decoder *decoder,
272 struct pt_packet *packet)
277 return -pte_internal;
279 packet->type = ppt_pad;
280 packet->size = ptps_pad;
285 int pt_pkt_decode_psb(struct pt_packet_decoder *decoder,
286 struct pt_packet *packet)
291 return -pte_internal;
293 size = pt_pkt_read_psb(decoder->pos, &decoder->config);
297 packet->type = ppt_psb;
298 packet->size = (uint8_t) size;
303 int pt_pkt_decode_tip(struct pt_packet_decoder *decoder,
304 struct pt_packet *packet)
308 if (!decoder || !packet)
309 return -pte_internal;
311 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
316 packet->type = ppt_tip;
317 packet->size = (uint8_t) size;
322 int pt_pkt_decode_tnt_8(struct pt_packet_decoder *decoder,
323 struct pt_packet *packet)
327 if (!decoder || !packet)
328 return -pte_internal;
330 size = pt_pkt_read_tnt_8(&packet->payload.tnt, decoder->pos,
335 packet->type = ppt_tnt_8;
336 packet->size = (uint8_t) size;
341 int pt_pkt_decode_tnt_64(struct pt_packet_decoder *decoder,
342 struct pt_packet *packet)
346 if (!decoder || !packet)
347 return -pte_internal;
349 size = pt_pkt_read_tnt_64(&packet->payload.tnt, decoder->pos,
354 packet->type = ppt_tnt_64;
355 packet->size = (uint8_t) size;
360 int pt_pkt_decode_tip_pge(struct pt_packet_decoder *decoder,
361 struct pt_packet *packet)
365 if (!decoder || !packet)
366 return -pte_internal;
368 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
373 packet->type = ppt_tip_pge;
374 packet->size = (uint8_t) size;
379 int pt_pkt_decode_tip_pgd(struct pt_packet_decoder *decoder,
380 struct pt_packet *packet)
384 if (!decoder || !packet)
385 return -pte_internal;
387 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
392 packet->type = ppt_tip_pgd;
393 packet->size = (uint8_t) size;
398 int pt_pkt_decode_fup(struct pt_packet_decoder *decoder,
399 struct pt_packet *packet)
403 if (!decoder || !packet)
404 return -pte_internal;
406 size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
411 packet->type = ppt_fup;
412 packet->size = (uint8_t) size;
417 int pt_pkt_decode_pip(struct pt_packet_decoder *decoder,
418 struct pt_packet *packet)
422 if (!decoder || !packet)
423 return -pte_internal;
425 size = pt_pkt_read_pip(&packet->payload.pip, decoder->pos,
430 packet->type = ppt_pip;
431 packet->size = (uint8_t) size;
436 int pt_pkt_decode_ovf(struct pt_packet_decoder *decoder,
437 struct pt_packet *packet)
442 return -pte_internal;
444 packet->type = ppt_ovf;
445 packet->size = ptps_ovf;
450 int pt_pkt_decode_mode(struct pt_packet_decoder *decoder,
451 struct pt_packet *packet)
455 if (!decoder || !packet)
456 return -pte_internal;
458 size = pt_pkt_read_mode(&packet->payload.mode, decoder->pos,
463 packet->type = ppt_mode;
464 packet->size = (uint8_t) size;
469 int pt_pkt_decode_psbend(struct pt_packet_decoder *decoder,
470 struct pt_packet *packet)
475 return -pte_internal;
477 packet->type = ppt_psbend;
478 packet->size = ptps_psbend;
483 int pt_pkt_decode_tsc(struct pt_packet_decoder *decoder,
484 struct pt_packet *packet)
488 if (!decoder || !packet)
489 return -pte_internal;
491 size = pt_pkt_read_tsc(&packet->payload.tsc, decoder->pos,
496 packet->type = ppt_tsc;
497 packet->size = (uint8_t) size;
502 int pt_pkt_decode_cbr(struct pt_packet_decoder *decoder,
503 struct pt_packet *packet)
507 if (!decoder || !packet)
508 return -pte_internal;
510 size = pt_pkt_read_cbr(&packet->payload.cbr, decoder->pos,
515 packet->type = ppt_cbr;
516 packet->size = (uint8_t) size;
521 int pt_pkt_decode_tma(struct pt_packet_decoder *decoder,
522 struct pt_packet *packet)
526 if (!decoder || !packet)
527 return -pte_internal;
529 size = pt_pkt_read_tma(&packet->payload.tma, decoder->pos,
534 packet->type = ppt_tma;
535 packet->size = (uint8_t) size;
540 int pt_pkt_decode_mtc(struct pt_packet_decoder *decoder,
541 struct pt_packet *packet)
545 if (!decoder || !packet)
546 return -pte_internal;
548 size = pt_pkt_read_mtc(&packet->payload.mtc, decoder->pos,
553 packet->type = ppt_mtc;
554 packet->size = (uint8_t) size;
559 int pt_pkt_decode_cyc(struct pt_packet_decoder *decoder,
560 struct pt_packet *packet)
564 if (!decoder || !packet)
565 return -pte_internal;
567 size = pt_pkt_read_cyc(&packet->payload.cyc, decoder->pos,
572 packet->type = ppt_cyc;
573 packet->size = (uint8_t) size;
578 int pt_pkt_decode_stop(struct pt_packet_decoder *decoder,
579 struct pt_packet *packet)
584 return -pte_internal;
586 packet->type = ppt_stop;
587 packet->size = ptps_stop;
592 int pt_pkt_decode_vmcs(struct pt_packet_decoder *decoder,
593 struct pt_packet *packet)
597 if (!decoder || !packet)
598 return -pte_internal;
600 size = pt_pkt_read_vmcs(&packet->payload.vmcs, decoder->pos,
605 packet->type = ppt_vmcs;
606 packet->size = (uint8_t) size;
611 int pt_pkt_decode_mnt(struct pt_packet_decoder *decoder,
612 struct pt_packet *packet)
616 if (!decoder || !packet)
617 return -pte_internal;
619 size = pt_pkt_read_mnt(&packet->payload.mnt, decoder->pos,
624 packet->type = ppt_mnt;
625 packet->size = (uint8_t) size;
630 int pt_pkt_decode_exstop(struct pt_packet_decoder *decoder,
631 struct pt_packet *packet)
635 if (!decoder || !packet)
636 return -pte_internal;
638 size = pt_pkt_read_exstop(&packet->payload.exstop, decoder->pos,
643 packet->type = ppt_exstop;
644 packet->size = (uint8_t) size;
649 int pt_pkt_decode_mwait(struct pt_packet_decoder *decoder,
650 struct pt_packet *packet)
654 if (!decoder || !packet)
655 return -pte_internal;
657 size = pt_pkt_read_mwait(&packet->payload.mwait, decoder->pos,
662 packet->type = ppt_mwait;
663 packet->size = (uint8_t) size;
668 int pt_pkt_decode_pwre(struct pt_packet_decoder *decoder,
669 struct pt_packet *packet)
673 if (!decoder || !packet)
674 return -pte_internal;
676 size = pt_pkt_read_pwre(&packet->payload.pwre, decoder->pos,
681 packet->type = ppt_pwre;
682 packet->size = (uint8_t) size;
687 int pt_pkt_decode_pwrx(struct pt_packet_decoder *decoder,
688 struct pt_packet *packet)
692 if (!decoder || !packet)
693 return -pte_internal;
695 size = pt_pkt_read_pwrx(&packet->payload.pwrx, decoder->pos,
700 packet->type = ppt_pwrx;
701 packet->size = (uint8_t) size;
706 int pt_pkt_decode_ptw(struct pt_packet_decoder *decoder,
707 struct pt_packet *packet)
711 if (!decoder || !packet)
712 return -pte_internal;
714 size = pt_pkt_read_ptw(&packet->payload.ptw, decoder->pos,
719 packet->type = ppt_ptw;
720 packet->size = (uint8_t) size;