1 /** @file 2 3 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 13 **/ 14 15 #include "Edb.h" 16 17 extern EDB_DISASM_INSTRUCTION mEdbDisasmInstructionTable[]; 18 19 typedef struct { 20 CHAR16 Name[EDB_INSTRUCTION_NAME_MAX_LENGTH]; 21 CHAR16 Content[EDB_INSTRUCTION_CONTENT_MAX_LENGTH]; 22 CHAR16 Tail; 23 } EDB_INSTRUCTION_STRING; 24 25 EDB_INSTRUCTION_STRING mInstructionString; 26 UINTN mInstructionNameOffset; 27 UINTN mInstructionContentOffset; 28 29 /** 30 31 Set offset for Instruction name and content. 32 33 @param InstructionNameOffset - Instruction name offset 34 @param InstructionContentOffset - Instruction content offset 35 36 **/ 37 VOID 38 EdbSetOffset ( 39 IN UINTN InstructionNameOffset, 40 IN UINTN InstructionContentOffset 41 ) 42 { 43 mInstructionNameOffset = InstructionNameOffset; 44 mInstructionContentOffset = InstructionContentOffset; 45 46 return ; 47 } 48 49 /** 50 51 Pre instruction string construction. 52 53 @return Instruction string 54 55 **/ 56 CHAR16 * 57 EdbPreInstructionString ( 58 VOID 59 ) 60 { 61 ZeroMem (&mInstructionString, sizeof(mInstructionString)); 62 mInstructionNameOffset = 0; 63 mInstructionContentOffset = 0; 64 65 return (CHAR16 *)&mInstructionString; 66 } 67 68 /** 69 70 Post instruction string construction. 71 72 @return Instruction string 73 74 **/ 75 CHAR16 * 76 EdbPostInstructionString ( 77 VOID 78 ) 79 { 80 CHAR16 *Char; 81 82 for (Char = (CHAR16 *)&mInstructionString; Char < &mInstructionString.Tail; Char++) { 83 if (*Char == 0) { 84 *Char = L' '; 85 } 86 } 87 mInstructionString.Tail = 0; 88 89 mInstructionNameOffset = 0; 90 mInstructionContentOffset = 0; 91 92 return (CHAR16 *)&mInstructionString; 93 } 94 95 /** 96 97 Get Sign, NaturalUnits, and ConstantUnits of the WORD data. 98 99 @param Data16 - WORD data 100 @param NaturalUnits - Natural Units of the WORD 101 @param ConstantUnits - Constant Units of the WORD 102 103 @return Sign value of WORD 104 105 **/ 106 BOOLEAN 107 EdbGetNaturalIndex16 ( 108 IN UINT16 Data16, 109 OUT UINTN *NaturalUnits, 110 OUT UINTN *ConstantUnits 111 ) 112 { 113 BOOLEAN Sign; 114 UINTN NaturalUnitBit; 115 116 Sign = (BOOLEAN)(Data16 >> 15); 117 NaturalUnitBit = (UINTN)((Data16 >> 12) & 0x7); 118 NaturalUnitBit *= 2; 119 Data16 = Data16 & 0xFFF; 120 *NaturalUnits = (UINTN)(Data16 & ((1 << NaturalUnitBit) - 1)); 121 *ConstantUnits = (UINTN)((Data16 >> NaturalUnitBit) & ((1 << (12 - NaturalUnitBit)) - 1)); 122 123 return Sign; 124 } 125 126 /** 127 128 Get Sign, NaturalUnits, and ConstantUnits of the DWORD data. 129 130 @param Data32 - DWORD data 131 @param NaturalUnits - Natural Units of the DWORD 132 @param ConstantUnits - Constant Units of the DWORD 133 134 @return Sign value of DWORD 135 136 **/ 137 BOOLEAN 138 EdbGetNaturalIndex32 ( 139 IN UINT32 Data32, 140 OUT UINTN *NaturalUnits, 141 OUT UINTN *ConstantUnits 142 ) 143 { 144 BOOLEAN Sign; 145 UINTN NaturalUnitBit; 146 147 Sign = (BOOLEAN)(Data32 >> 31); 148 NaturalUnitBit = (UINTN)((Data32 >> 28) & 0x7); 149 NaturalUnitBit *= 4; 150 Data32 = Data32 & 0xFFFFFFF; 151 *NaturalUnits = (UINTN)(Data32 & ((1 << NaturalUnitBit) - 1)); 152 *ConstantUnits = (UINTN)((Data32 >> NaturalUnitBit) & ((1 << (28 - NaturalUnitBit)) - 1)); 153 154 return Sign; 155 } 156 157 /** 158 159 Get Sign, NaturalUnits, and ConstantUnits of the QWORD data. 160 161 @param Data64 - QWORD data 162 @param NaturalUnits - Natural Units of the QWORD 163 @param ConstantUnits - Constant Units of the QWORD 164 165 @return Sign value of QWORD 166 167 **/ 168 BOOLEAN 169 EdbGetNaturalIndex64 ( 170 IN UINT64 Data64, 171 OUT UINT64 *NaturalUnits, 172 OUT UINT64 *ConstantUnits 173 ) 174 { 175 BOOLEAN Sign; 176 UINTN NaturalUnitBit; 177 178 Sign = (BOOLEAN)RShiftU64 (Data64, 63); 179 NaturalUnitBit = (UINTN)(RShiftU64 (Data64, 60) & 0x7); 180 NaturalUnitBit *= 8; 181 Data64 = RShiftU64 (LShiftU64 (Data64, 4), 4); 182 *NaturalUnits = (UINT64)(Data64 & (LShiftU64 (1, NaturalUnitBit) - 1)); 183 *ConstantUnits = (UINT64)(RShiftU64 (Data64, NaturalUnitBit) & (LShiftU64 (1, (60 - NaturalUnitBit)) - 1)); 184 185 return Sign; 186 } 187 188 /** 189 190 Get Bit Width of the value. 191 192 @param Value - data 193 194 @return Bit width 195 196 **/ 197 UINT8 198 EdbGetBitWidth ( 199 IN UINT64 Value 200 ) 201 { 202 if (Value >= 10000000000000) { 203 return 14; 204 } else if (Value >= 1000000000000) { 205 return 13; 206 } else if (Value >= 100000000000) { 207 return 12; 208 } else if (Value >= 10000000000) { 209 return 11; 210 } else if (Value >= 1000000000) { 211 return 10; 212 } else if (Value >= 100000000) { 213 return 9; 214 } else if (Value >= 10000000) { 215 return 8; 216 } else if (Value >= 1000000) { 217 return 7; 218 } else if (Value >= 100000) { 219 return 6; 220 } else if (Value >= 10000) { 221 return 5; 222 } else if (Value >= 1000) { 223 return 4; 224 } else if (Value >= 100) { 225 return 3; 226 } else if (Value >= 10) { 227 return 2; 228 } else { 229 return 1; 230 } 231 } 232 233 /** 234 235 Print the instruction name. 236 237 @param Name - instruction name 238 239 @return Instruction name offset 240 241 **/ 242 UINTN 243 EdbPrintInstructionName ( 244 IN CHAR16 *Name 245 ) 246 { 247 EDBSPrintWithOffset ( 248 mInstructionString.Name, 249 EDB_INSTRUCTION_NAME_MAX_SIZE, 250 mInstructionNameOffset, 251 L"%s", 252 Name 253 ); 254 mInstructionNameOffset += StrLen (Name); 255 256 return mInstructionNameOffset; 257 } 258 259 /** 260 261 Print register 1 in operands. 262 263 @param Operands - instruction operands 264 265 @return Instruction content offset 266 267 **/ 268 UINTN 269 EdbPrintRegister1 ( 270 IN UINT8 Operands 271 ) 272 { 273 if ((Operands & OPERAND_M_INDIRECT1) != 0) { 274 EDBSPrintWithOffset ( 275 mInstructionString.Content, 276 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 277 mInstructionContentOffset, 278 L"@" 279 ); 280 mInstructionContentOffset += 1; 281 } 282 EDBSPrintWithOffset ( 283 mInstructionString.Content, 284 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 285 mInstructionContentOffset, 286 L"R%d", 287 (UINTN)(Operands & OPERAND_M_OP1) 288 ); 289 mInstructionContentOffset += 2; 290 291 return mInstructionContentOffset; 292 } 293 294 /** 295 296 Print register 2 in operands. 297 298 @param Operands - instruction operands 299 300 @return Instruction content offset 301 302 **/ 303 UINTN 304 EdbPrintRegister2 ( 305 IN UINT8 Operands 306 ) 307 { 308 if ((Operands & OPERAND_M_INDIRECT2) != 0) { 309 EDBSPrintWithOffset ( 310 mInstructionString.Content, 311 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 312 mInstructionContentOffset, 313 L"@" 314 ); 315 mInstructionContentOffset += 1; 316 } 317 EDBSPrintWithOffset ( 318 mInstructionString.Content, 319 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 320 mInstructionContentOffset, 321 L"R%d", 322 (UINTN)((Operands & OPERAND_M_OP2) >> 4) 323 ); 324 mInstructionContentOffset += 2; 325 326 return mInstructionContentOffset; 327 } 328 329 /** 330 331 Print dedicated register 1 in operands. 332 333 @param Operands - instruction operands 334 335 @return Instruction content offset 336 337 **/ 338 UINTN 339 EdbPrintDedicatedRegister1 ( 340 IN UINT8 Operands 341 ) 342 { 343 switch (Operands & OPERAND_M_OP1) { 344 case 0: 345 EDBSPrintWithOffset ( 346 mInstructionString.Content, 347 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 348 mInstructionContentOffset, 349 L"[FLAGS]" 350 ); 351 mInstructionContentOffset += 7; 352 break; 353 case 1: 354 EDBSPrintWithOffset ( 355 mInstructionString.Content, 356 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 357 mInstructionContentOffset, 358 L"[IP]" 359 ); 360 mInstructionContentOffset += 4; 361 break; 362 } 363 364 return mInstructionContentOffset; 365 } 366 367 /** 368 369 Print dedicated register 2 in operands. 370 371 @param Operands - instruction operands 372 373 @return Instruction content offset 374 375 **/ 376 UINTN 377 EdbPrintDedicatedRegister2 ( 378 IN UINT8 Operands 379 ) 380 { 381 switch ((Operands & OPERAND_M_OP2) >> 4) { 382 case 0: 383 EDBSPrintWithOffset ( 384 mInstructionString.Content, 385 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 386 mInstructionContentOffset, 387 L"[FLAGS]" 388 ); 389 mInstructionContentOffset += 7; 390 break; 391 case 1: 392 EDBSPrintWithOffset ( 393 mInstructionString.Content, 394 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 395 mInstructionContentOffset, 396 L"[IP]" 397 ); 398 mInstructionContentOffset += 4; 399 break; 400 } 401 402 return mInstructionContentOffset; 403 } 404 405 /** 406 407 Print the hexical UINTN index data to instruction content. 408 409 @param Sign - Signed bit of UINTN data 410 @param NaturalUnits - natural units of UINTN data 411 @param ConstantUnits - natural units of UINTN data 412 413 @return Instruction content offset 414 415 **/ 416 UINTN 417 EdbPrintIndexData ( 418 IN BOOLEAN Sign, 419 IN UINTN NaturalUnits, 420 IN UINTN ConstantUnits 421 ) 422 { 423 EDBSPrintWithOffset ( 424 mInstructionString.Content, 425 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 426 mInstructionContentOffset, 427 L"(%s%d,%s%d)", 428 Sign ? L"-" : L"+", 429 NaturalUnits, 430 Sign ? L"-" : L"+", 431 ConstantUnits 432 ); 433 mInstructionContentOffset = mInstructionContentOffset + 5 + EdbGetBitWidth (NaturalUnits) + EdbGetBitWidth (ConstantUnits); 434 435 return mInstructionContentOffset; 436 } 437 438 /** 439 440 Print the hexical QWORD index data to instruction content. 441 442 @param Sign - Signed bit of QWORD data 443 @param NaturalUnits - natural units of QWORD data 444 @param ConstantUnits - natural units of QWORD data 445 446 @return Instruction content offset 447 448 **/ 449 UINTN 450 EdbPrintIndexData64 ( 451 IN BOOLEAN Sign, 452 IN UINT64 NaturalUnits, 453 IN UINT64 ConstantUnits 454 ) 455 { 456 EDBSPrintWithOffset ( 457 mInstructionString.Content, 458 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 459 mInstructionContentOffset, 460 L"(%s%ld,%s%ld)", 461 Sign ? L"-" : L"+", 462 NaturalUnits, 463 Sign ? L"-" : L"+", 464 ConstantUnits 465 ); 466 mInstructionContentOffset = mInstructionContentOffset + 5 + EdbGetBitWidth (NaturalUnits) + EdbGetBitWidth (ConstantUnits); 467 468 return mInstructionContentOffset; 469 } 470 471 /** 472 473 Print the hexical WORD raw index data to instruction content. 474 475 @param Data16 - WORD data 476 477 @return Instruction content offset 478 479 **/ 480 UINTN 481 EdbPrintRawIndexData16 ( 482 IN UINT16 Data16 483 ) 484 { 485 BOOLEAN Sign; 486 UINTN NaturalUnits; 487 UINTN ConstantUnits; 488 UINTN Offset; 489 490 Sign = EdbGetNaturalIndex16 (Data16, &NaturalUnits, &ConstantUnits); 491 Offset = EdbPrintIndexData (Sign, NaturalUnits, ConstantUnits); 492 493 return Offset; 494 } 495 496 /** 497 498 Print the hexical DWORD raw index data to instruction content. 499 500 @param Data32 - DWORD data 501 502 @return Instruction content offset 503 504 **/ 505 UINTN 506 EdbPrintRawIndexData32 ( 507 IN UINT32 Data32 508 ) 509 { 510 BOOLEAN Sign; 511 UINTN NaturalUnits; 512 UINTN ConstantUnits; 513 UINTN Offset; 514 515 Sign = EdbGetNaturalIndex32 (Data32, &NaturalUnits, &ConstantUnits); 516 Offset = EdbPrintIndexData (Sign, NaturalUnits, ConstantUnits); 517 518 return Offset; 519 } 520 521 /** 522 523 Print the hexical QWORD raw index data to instruction content. 524 525 @param Data64 - QWORD data 526 527 @return Instruction content offset 528 529 **/ 530 UINTN 531 EdbPrintRawIndexData64 ( 532 IN UINT64 Data64 533 ) 534 { 535 BOOLEAN Sign; 536 UINT64 NaturalUnits; 537 UINT64 ConstantUnits; 538 UINTN Offset; 539 540 Sign = EdbGetNaturalIndex64 (Data64, &NaturalUnits, &ConstantUnits); 541 Offset = EdbPrintIndexData64 (Sign, NaturalUnits, ConstantUnits); 542 543 return Offset; 544 } 545 546 /** 547 548 Print the hexical BYTE immediate data to instruction content. 549 550 @param Data - BYTE data 551 552 @return Instruction content offset 553 554 **/ 555 UINTN 556 EdbPrintImmData8 ( 557 IN UINT8 Data 558 ) 559 { 560 EDBSPrintWithOffset ( 561 mInstructionString.Content, 562 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 563 mInstructionContentOffset, 564 L"(0x%02x)", 565 (UINTN)Data 566 ); 567 mInstructionContentOffset += 6; 568 569 return mInstructionContentOffset; 570 } 571 572 /** 573 574 Print the hexical WORD immediate data to instruction content. 575 576 @param Data - WORD data 577 578 @return Instruction content offset 579 580 **/ 581 UINTN 582 EdbPrintImmData16 ( 583 IN UINT16 Data 584 ) 585 { 586 EDBSPrintWithOffset ( 587 mInstructionString.Content, 588 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 589 mInstructionContentOffset, 590 L"(0x%04x)", 591 (UINTN)Data 592 ); 593 mInstructionContentOffset += 8; 594 595 return mInstructionContentOffset; 596 } 597 598 /** 599 600 Print the hexical DWORD immediate data to instruction content. 601 602 @param Data - DWORD data 603 604 @return Instruction content offset 605 606 **/ 607 UINTN 608 EdbPrintImmData32 ( 609 IN UINT32 Data 610 ) 611 { 612 EDBSPrintWithOffset ( 613 mInstructionString.Content, 614 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 615 mInstructionContentOffset, 616 L"(0x%08x)", 617 (UINTN)Data 618 ); 619 mInstructionContentOffset += 12; 620 621 return mInstructionContentOffset; 622 } 623 624 /** 625 626 Print the hexical QWORD immediate data to instruction content. 627 628 @param Data - QWORD data 629 630 @return Instruction content offset 631 632 **/ 633 UINTN 634 EdbPrintImmData64 ( 635 IN UINT64 Data 636 ) 637 { 638 EDBSPrintWithOffset ( 639 mInstructionString.Content, 640 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 641 mInstructionContentOffset, 642 L"(0x%016lx)", 643 Data 644 ); 645 mInstructionContentOffset += 20; 646 647 return mInstructionContentOffset; 648 } 649 650 /** 651 652 Print the decimal UINTN immediate data to instruction content. 653 654 @param Data - UINTN data 655 656 @return Instruction content offset 657 658 **/ 659 UINTN 660 EdbPrintImmDatan ( 661 IN UINTN Data 662 ) 663 { 664 EDBSPrintWithOffset ( 665 mInstructionString.Content, 666 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 667 mInstructionContentOffset, 668 L"(%d)", 669 (UINTN)Data 670 ); 671 mInstructionContentOffset = mInstructionContentOffset + 2 + EdbGetBitWidth (Data); 672 673 return mInstructionContentOffset; 674 } 675 676 /** 677 678 Print the decimal QWORD immediate data to instruction content. 679 680 @param Data64 - QWORD data 681 682 @return Instruction content offset 683 684 **/ 685 UINTN 686 EdbPrintImmData64n ( 687 IN UINT64 Data64 688 ) 689 { 690 EDBSPrintWithOffset ( 691 mInstructionString.Content, 692 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 693 mInstructionContentOffset, 694 L"(%ld)", 695 Data64 696 ); 697 mInstructionContentOffset = mInstructionContentOffset + 2 + EdbGetBitWidth (Data64); 698 699 return mInstructionContentOffset; 700 } 701 702 /** 703 704 Print the hexical BYTE to instruction content. 705 706 @param Data8 - BYTE data 707 708 @return Instruction content offset 709 710 **/ 711 UINTN 712 EdbPrintData8 ( 713 IN UINT8 Data8 714 ) 715 { 716 EDBSPrintWithOffset ( 717 mInstructionString.Content, 718 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 719 mInstructionContentOffset, 720 L"0x%02x", 721 (UINTN)Data8 722 ); 723 mInstructionContentOffset += 4; 724 725 return mInstructionContentOffset; 726 } 727 728 /** 729 730 Print the hexical WORD to instruction content. 731 732 @param Data16 - WORD data 733 734 @return Instruction content offset 735 736 **/ 737 UINTN 738 EdbPrintData16 ( 739 IN UINT16 Data16 740 ) 741 { 742 EDBSPrintWithOffset ( 743 mInstructionString.Content, 744 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 745 mInstructionContentOffset, 746 L"0x%04x", 747 (UINTN)Data16 748 ); 749 mInstructionContentOffset += 6; 750 751 return mInstructionContentOffset; 752 } 753 754 /** 755 756 Print the hexical DWORD to instruction content. 757 758 @param Data32 - DWORD data 759 760 @return Instruction content offset 761 762 **/ 763 UINTN 764 EdbPrintData32 ( 765 IN UINT32 Data32 766 ) 767 { 768 EDBSPrintWithOffset ( 769 mInstructionString.Content, 770 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 771 mInstructionContentOffset, 772 L"0x%08x", 773 (UINTN)Data32 774 ); 775 mInstructionContentOffset += 10; 776 777 return mInstructionContentOffset; 778 } 779 780 /** 781 782 Print the hexical QWORD to instruction content. 783 784 @param Data64 - QWORD data 785 786 @return Instruction content offset 787 788 **/ 789 UINTN 790 EdbPrintData64 ( 791 IN UINT64 Data64 792 ) 793 { 794 EDBSPrintWithOffset ( 795 mInstructionString.Content, 796 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 797 mInstructionContentOffset, 798 L"0x%016lx", 799 (UINT64)Data64 800 ); 801 mInstructionContentOffset += 18; 802 803 return mInstructionContentOffset; 804 } 805 806 /** 807 808 Print the decimal unsigned UINTN to instruction content. 809 810 @param Data - unsigned UINTN data 811 812 @return Instruction content offset 813 814 **/ 815 UINTN 816 EdbPrintDatan ( 817 IN UINTN Data 818 ) 819 { 820 EDBSPrintWithOffset ( 821 mInstructionString.Content, 822 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 823 mInstructionContentOffset, 824 L"%d", 825 (UINTN)Data 826 ); 827 mInstructionContentOffset = mInstructionContentOffset + EdbGetBitWidth (Data); 828 829 return mInstructionContentOffset; 830 } 831 832 /** 833 834 Print the decimal unsigned QWORD to instruction content. 835 836 @param Data64 - unsigned QWORD data 837 838 @return Instruction content offset 839 840 **/ 841 UINTN 842 EdbPrintData64n ( 843 IN UINT64 Data64 844 ) 845 { 846 EDBSPrintWithOffset ( 847 mInstructionString.Content, 848 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 849 mInstructionContentOffset, 850 L"%ld", 851 Data64 852 ); 853 mInstructionContentOffset = mInstructionContentOffset + EdbGetBitWidth (Data64); 854 855 return mInstructionContentOffset; 856 } 857 858 /** 859 860 Print the decimal signed BYTE to instruction content. 861 862 @param Data8 - signed BYTE data 863 864 @return Instruction content offset 865 866 **/ 867 UINTN 868 EdbPrintData8s ( 869 IN UINT8 Data8 870 ) 871 { 872 BOOLEAN Sign; 873 874 Sign = (BOOLEAN)(Data8 >> 7); 875 876 EDBSPrintWithOffset ( 877 mInstructionString.Content, 878 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 879 mInstructionContentOffset, 880 L"%s%d", 881 Sign ? L"-" : L"+", 882 (UINTN)(Data8 & 0x7F) 883 ); 884 mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data8 & 0x7F); 885 886 return mInstructionContentOffset; 887 } 888 889 /** 890 891 Print the decimal signed WORD to instruction content. 892 893 @param Data16 - signed WORD data 894 895 @return Instruction content offset 896 897 **/ 898 UINTN 899 EdbPrintData16s ( 900 IN UINT16 Data16 901 ) 902 { 903 BOOLEAN Sign; 904 905 Sign = (BOOLEAN)(Data16 >> 15); 906 907 EDBSPrintWithOffset ( 908 mInstructionString.Content, 909 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 910 mInstructionContentOffset, 911 L"%s%d", 912 Sign ? L"-" : L"+", 913 (UINTN)(Data16 & 0x7FFF) 914 ); 915 mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data16 & 0x7FFF); 916 917 return mInstructionContentOffset; 918 } 919 920 /** 921 922 Print the decimal signed DWORD to instruction content. 923 924 @param Data32 - signed DWORD data 925 926 @return Instruction content offset 927 928 **/ 929 UINTN 930 EdbPrintData32s ( 931 IN UINT32 Data32 932 ) 933 { 934 BOOLEAN Sign; 935 936 Sign = (BOOLEAN)(Data32 >> 31); 937 938 EDBSPrintWithOffset ( 939 mInstructionString.Content, 940 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 941 mInstructionContentOffset, 942 L"%s%d", 943 Sign ? L"-" : L"+", 944 (UINTN)(Data32 & 0x7FFFFFFF) 945 ); 946 mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data32 & 0x7FFFFFFF); 947 948 return mInstructionContentOffset; 949 } 950 951 /** 952 953 Print the decimal signed QWORD to instruction content. 954 955 @param Data64 - signed QWORD data 956 957 @return Instruction content offset 958 959 **/ 960 UINTN 961 EdbPrintData64s ( 962 IN UINT64 Data64 963 ) 964 { 965 BOOLEAN Sign; 966 INT64 Data64s; 967 968 Sign = (BOOLEAN)RShiftU64 (Data64, 63); 969 Data64s = (INT64)RShiftU64 (LShiftU64 (Data64, 1), 1); 970 971 EDBSPrintWithOffset ( 972 mInstructionString.Content, 973 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 974 mInstructionContentOffset, 975 L"%s%ld", 976 Sign ? L"-" : L"+", 977 (UINT64)Data64s 978 ); 979 mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data64s); 980 981 return mInstructionContentOffset; 982 } 983 984 /** 985 986 Print the comma to instruction content. 987 988 @return Instruction content offset 989 990 **/ 991 UINTN 992 EdbPrintComma ( 993 VOID 994 ) 995 { 996 EDBSPrintWithOffset ( 997 mInstructionString.Content, 998 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 999 mInstructionContentOffset, 1000 L", " 1001 ); 1002 mInstructionContentOffset += 2; 1003 1004 return mInstructionContentOffset; 1005 } 1006 1007 /** 1008 1009 Find the symbol string according to address, then print it. 1010 1011 @param Address - instruction address 1012 1013 @retval 1 - symbol string is found and printed 1014 @retval 0 - symbol string not found 1015 1016 **/ 1017 UINTN 1018 EdbFindAndPrintSymbol ( 1019 IN UINTN Address 1020 ) 1021 { 1022 CHAR8 *SymbolStr; 1023 1024 SymbolStr = FindSymbolStr (Address); 1025 if (SymbolStr != NULL) { 1026 EDBSPrintWithOffset ( 1027 mInstructionString.Content, 1028 EDB_INSTRUCTION_CONTENT_MAX_SIZE, 1029 mInstructionContentOffset, 1030 L"[%a]", 1031 SymbolStr 1032 ); 1033 return 1; 1034 } 1035 1036 return 0; 1037 } 1038 1039 /** 1040 1041 Print the EBC byte code. 1042 1043 @param InstructionAddress - instruction address 1044 @param InstructionNumber - instruction number 1045 1046 **/ 1047 VOID 1048 EdbPrintRaw ( 1049 IN EFI_PHYSICAL_ADDRESS InstructionAddress, 1050 IN UINTN InstructionNumber 1051 ) 1052 { 1053 UINTN LineNumber; 1054 UINTN ByteNumber; 1055 UINTN LineIndex; 1056 UINTN ByteIndex; 1057 CHAR8 *SymbolStr; 1058 1059 if (InstructionNumber == 0) { 1060 return ; 1061 } 1062 1063 LineNumber = InstructionNumber / EDB_BYTECODE_NUMBER_IN_LINE; 1064 ByteNumber = InstructionNumber % EDB_BYTECODE_NUMBER_IN_LINE; 1065 if (ByteNumber == 0) { 1066 LineNumber -= 1; 1067 ByteNumber = EDB_BYTECODE_NUMBER_IN_LINE; 1068 } 1069 1070 // 1071 // Print Symbol 1072 // 1073 SymbolStr = FindSymbolStr ((UINTN)InstructionAddress); 1074 if (SymbolStr != NULL) { 1075 EDBPrint (L"[%a]:\n", SymbolStr); 1076 } 1077 1078 for (LineIndex = 0; LineIndex < LineNumber; LineIndex++) { 1079 EDBPrint (EDB_PRINT_ADDRESS_FORMAT, (UINTN)InstructionAddress); 1080 for (ByteIndex = 0; ByteIndex < EDB_BYTECODE_NUMBER_IN_LINE; ByteIndex++) { 1081 EDBPrint (L"%02x ", *(UINT8 *)(UINTN)InstructionAddress); 1082 InstructionAddress += 1; 1083 } 1084 EDBPrint (L"\n"); 1085 } 1086 1087 EDBPrint (EDB_PRINT_ADDRESS_FORMAT, (UINTN)InstructionAddress); 1088 for (ByteIndex = 0; ByteIndex < ByteNumber; ByteIndex++) { 1089 EDBPrint (L"%02x ", *(UINT8 *)(UINTN)InstructionAddress); 1090 InstructionAddress += 1; 1091 } 1092 for (ByteIndex = 0; ByteIndex < EDB_BYTECODE_NUMBER_IN_LINE - ByteNumber; ByteIndex++) { 1093 EDBPrint (L" "); 1094 } 1095 1096 return ; 1097 } 1098 1099 /** 1100 1101 Print the EBC asm code. 1102 1103 @param DebuggerPrivate - EBC Debugger private data structure 1104 @param SystemContext - EBC system context. 1105 1106 @retval EFI_SUCCESS - show disasm successfully 1107 1108 **/ 1109 EFI_STATUS 1110 EdbShowDisasm ( 1111 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, 1112 IN EFI_SYSTEM_CONTEXT SystemContext 1113 ) 1114 { 1115 EFI_PHYSICAL_ADDRESS InstructionAddress; 1116 UINTN InstructionNumber; 1117 UINTN InstructionLength; 1118 UINT8 Opcode; 1119 CHAR16 *InstructionString; 1120 // UINTN Result; 1121 1122 InstructionAddress = DebuggerPrivate->InstructionScope; 1123 for (InstructionNumber = 0; InstructionNumber < DebuggerPrivate->InstructionNumber; InstructionNumber++) { 1124 1125 // 1126 // Break each 0x10 instruction 1127 // 1128 if (((InstructionNumber % EFI_DEBUGGER_LINE_NUMBER_IN_PAGE) == 0) && 1129 (InstructionNumber != 0)) { 1130 if (SetPageBreak ()) { 1131 break; 1132 } 1133 } 1134 1135 Opcode = GET_OPCODE(InstructionAddress); 1136 if ((Opcode < OPCODE_MAX) && (mEdbDisasmInstructionTable[Opcode] != NULL)) { 1137 InstructionLength = mEdbDisasmInstructionTable [Opcode] (InstructionAddress, SystemContext, &InstructionString); 1138 if (InstructionLength != 0) { 1139 1140 // 1141 // Print Source 1142 // 1143 // Result = EdbPrintSource ((UINTN)InstructionAddress, FALSE); 1144 1145 if (!DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly) { 1146 1147 EdbPrintRaw (InstructionAddress, InstructionLength); 1148 if (InstructionString != NULL) { 1149 EDBPrint (L"%s\n", InstructionString); 1150 } else { 1151 EDBPrint (L"%s\n", L"<Unknown Instruction>"); 1152 } 1153 } 1154 1155 EdbPrintSource ((UINTN)InstructionAddress, TRUE); 1156 1157 InstructionAddress += InstructionLength; 1158 } else { 1159 // 1160 // Something wrong with OPCODE 1161 // 1162 EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE); 1163 EDBPrint (L"%s\n", L"<Bad Instruction>"); 1164 break; 1165 } 1166 } else { 1167 // 1168 // Something wrong with OPCODE 1169 // 1170 EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE); 1171 EDBPrint (L"%s\n", L"<Bad Instruction>"); 1172 break; 1173 } 1174 } 1175 1176 return EFI_SUCCESS; 1177 } 1178 1179 /** 1180 1181 Get register value accroding to the system context, and register index. 1182 1183 @param SystemContext - EBC system context. 1184 @param Index - EBC register index 1185 1186 @return register value 1187 1188 **/ 1189 UINT64 1190 GetRegisterValue ( 1191 IN EFI_SYSTEM_CONTEXT SystemContext, 1192 IN UINT8 Index 1193 ) 1194 { 1195 switch (Index) { 1196 case 0: 1197 return SystemContext.SystemContextEbc->R0; 1198 case 1: 1199 return SystemContext.SystemContextEbc->R1; 1200 case 2: 1201 return SystemContext.SystemContextEbc->R2; 1202 case 3: 1203 return SystemContext.SystemContextEbc->R3; 1204 case 4: 1205 return SystemContext.SystemContextEbc->R4; 1206 case 5: 1207 return SystemContext.SystemContextEbc->R5; 1208 case 6: 1209 return SystemContext.SystemContextEbc->R6; 1210 case 7: 1211 return SystemContext.SystemContextEbc->R7; 1212 default: 1213 ASSERT (FALSE); 1214 break; 1215 } 1216 return 0; 1217 } 1218