]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/processor-trace/libipt/src/pt_packet_decoder.c
Merge release 1.14 of bsnmp.
[FreeBSD/FreeBSD.git] / contrib / processor-trace / libipt / src / pt_packet_decoder.c
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 }