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