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 "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. */ 41 struct 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 56 static 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 70 static struct ptunit_result ffix_fini(struct fetch_fixture *ffix) 71 { 72 pt_encoder_fini(&ffix->encoder); 73 74 return ptu_passed(); 75 } 76 77 78 static 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 95 static 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 106 static 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 120 static 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 135 static 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 151 static 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 168 static 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 182 static 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 195 static 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 208 static 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 221 static 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 234 int 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 */ 289 int 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 } 296 int pt_qry_decode_unknown(struct pt_query_decoder *d) 297 { 298 (void) d; 299 300 return -pte_internal; 301 } 302 303 int 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 } 310 int pt_qry_decode_pad(struct pt_query_decoder *d) 311 { 312 (void) d; 313 314 return -pte_internal; 315 } 316 317 int 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 } 324 int pt_qry_decode_psb(struct pt_query_decoder *d) 325 { 326 (void) d; 327 328 return -pte_internal; 329 } 330 331 int 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 } 338 int pt_qry_decode_tip(struct pt_query_decoder *d) 339 { 340 (void) d; 341 342 return -pte_internal; 343 } 344 345 int 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 } 352 int pt_qry_decode_tnt_8(struct pt_query_decoder *d) 353 { 354 (void) d; 355 356 return -pte_internal; 357 } 358 359 int 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 } 366 int pt_qry_decode_tnt_64(struct pt_query_decoder *d) 367 { 368 (void) d; 369 370 return -pte_internal; 371 } 372 373 int 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 } 380 int pt_qry_decode_tip_pge(struct pt_query_decoder *d) 381 { 382 (void) d; 383 384 return -pte_internal; 385 } 386 387 int 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 } 394 int pt_qry_decode_tip_pgd(struct pt_query_decoder *d) 395 { 396 (void) d; 397 398 return -pte_internal; 399 } 400 401 int 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 } 408 int pt_qry_decode_fup(struct pt_query_decoder *d) 409 { 410 (void) d; 411 412 return -pte_internal; 413 } 414 int pt_qry_header_fup(struct pt_query_decoder *d) 415 { 416 (void) d; 417 418 return -pte_internal; 419 } 420 421 int 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 } 428 int pt_qry_decode_pip(struct pt_query_decoder *d) 429 { 430 (void) d; 431 432 return -pte_internal; 433 } 434 int pt_qry_header_pip(struct pt_query_decoder *d) 435 { 436 (void) d; 437 438 return -pte_internal; 439 } 440 441 int 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 } 448 int pt_qry_decode_ovf(struct pt_query_decoder *d) 449 { 450 (void) d; 451 452 return -pte_internal; 453 } 454 455 int 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 } 462 int pt_qry_decode_mode(struct pt_query_decoder *d) 463 { 464 (void) d; 465 466 return -pte_internal; 467 } 468 int pt_qry_header_mode(struct pt_query_decoder *d) 469 { 470 (void) d; 471 472 return -pte_internal; 473 } 474 475 int 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 } 482 int pt_qry_decode_psbend(struct pt_query_decoder *d) 483 { 484 (void) d; 485 486 return -pte_internal; 487 } 488 489 int 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 } 496 int pt_qry_decode_tsc(struct pt_query_decoder *d) 497 { 498 (void) d; 499 500 return -pte_internal; 501 } 502 int pt_qry_header_tsc(struct pt_query_decoder *d) 503 { 504 (void) d; 505 506 return -pte_internal; 507 } 508 509 int 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 } 516 int pt_qry_decode_cbr(struct pt_query_decoder *d) 517 { 518 (void) d; 519 520 return -pte_internal; 521 } 522 int pt_qry_header_cbr(struct pt_query_decoder *d) 523 { 524 (void) d; 525 526 return -pte_internal; 527 } 528 529 int 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 } 536 int pt_qry_decode_tma(struct pt_query_decoder *d) 537 { 538 (void) d; 539 540 return -pte_internal; 541 } 542 543 int 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 } 550 int pt_qry_decode_mtc(struct pt_query_decoder *d) 551 { 552 (void) d; 553 554 return -pte_internal; 555 } 556 557 int 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 } 564 int pt_qry_decode_cyc(struct pt_query_decoder *d) 565 { 566 (void) d; 567 568 return -pte_internal; 569 } 570 571 int 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 } 578 int pt_qry_decode_stop(struct pt_query_decoder *d) 579 { 580 (void) d; 581 582 return -pte_internal; 583 } 584 585 int 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 } 592 int pt_qry_decode_vmcs(struct pt_query_decoder *d) 593 { 594 (void) d; 595 596 return -pte_internal; 597 } 598 int pt_qry_header_vmcs(struct pt_query_decoder *d) 599 { 600 (void) d; 601 602 return -pte_internal; 603 } 604 605 int 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 } 612 int pt_qry_decode_mnt(struct pt_query_decoder *d) 613 { 614 (void) d; 615 616 return -pte_internal; 617 } 618 int pt_qry_header_mnt(struct pt_query_decoder *d) 619 { 620 (void) d; 621 622 return -pte_internal; 623 } 624 625 int 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 } 632 int pt_qry_decode_exstop(struct pt_query_decoder *d) 633 { 634 (void) d; 635 636 return -pte_internal; 637 } 638 639 int 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 } 646 int pt_qry_decode_mwait(struct pt_query_decoder *d) 647 { 648 (void) d; 649 650 return -pte_internal; 651 } 652 653 int 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 } 660 int pt_qry_decode_pwre(struct pt_query_decoder *d) 661 { 662 (void) d; 663 664 return -pte_internal; 665 } 666 667 int 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 } 674 int pt_qry_decode_pwrx(struct pt_query_decoder *d) 675 { 676 (void) d; 677 678 return -pte_internal; 679 } 680 681 int 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 } 688 int pt_qry_decode_ptw(struct pt_query_decoder *d) 689 { 690 (void) d; 691 692 return -pte_internal; 693 } 694