| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 /* | 7 /* |
| 8 * Hand-written Ragel machines and actions used in validator and decoding. | 8 * Hand-written Ragel machines and actions used in validator and decoding. |
| 9 * | 9 * |
| 10 * Note: this file includes many different machines which are supposed to be | 10 * Note: this file includes many different machines which are supposed to be |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 VEX_RX = b_xx1_xxxxx @vex_prefix2; | 243 VEX_RX = b_xx1_xxxxx @vex_prefix2; |
| 244 VEX_RB = b_x1x_xxxxx @vex_prefix2; | 244 VEX_RB = b_x1x_xxxxx @vex_prefix2; |
| 245 VEX_XB = b_1xx_xxxxx @vex_prefix2; | 245 VEX_XB = b_1xx_xxxxx @vex_prefix2; |
| 246 VEX_RXB = b_xxx_xxxxx @vex_prefix2; | 246 VEX_RXB = b_xxx_xxxxx @vex_prefix2; |
| 247 }%% | 247 }%% |
| 248 | 248 |
| 249 %%{ | 249 %%{ |
| 250 machine modrm_actions_ia32; | 250 machine modrm_actions_ia32; |
| 251 | 251 |
| 252 action modrm_only_base { | 252 action modrm_only_base { |
| 253 SET_DISP_TYPE(DISPNONE); | 253 SET_DISPLACEMENT_FORMAT(DISPNONE); |
| 254 SET_MODRM_BASE(RMFromModRM(*current_position)); | 254 SET_MODRM_BASE(RMFromModRM(*current_position)); |
| 255 SET_MODRM_INDEX(NO_REG); | 255 SET_MODRM_INDEX(NO_REG); |
| 256 SET_MODRM_SCALE(0); | 256 SET_MODRM_SCALE(0); |
| 257 } | 257 } |
| 258 action modrm_base_disp { | 258 action modrm_base_disp { |
| 259 SET_MODRM_BASE(RMFromModRM(*current_position)); | 259 SET_MODRM_BASE(RMFromModRM(*current_position)); |
| 260 SET_MODRM_INDEX(NO_REG); | 260 SET_MODRM_INDEX(NO_REG); |
| 261 SET_MODRM_SCALE(0); | 261 SET_MODRM_SCALE(0); |
| 262 } | 262 } |
| 263 action modrm_pure_disp { | 263 action modrm_pure_disp { |
| 264 // Case where ModRM.mod = 00 and ModRM.r/m = 101. | 264 // Case where ModRM.mod = 00 and ModRM.r/m = 101. |
| 265 SET_MODRM_BASE(NO_REG); | 265 SET_MODRM_BASE(NO_REG); |
| 266 SET_MODRM_INDEX(NO_REG); | 266 SET_MODRM_INDEX(NO_REG); |
| 267 SET_MODRM_SCALE(0); | 267 SET_MODRM_SCALE(0); |
| 268 } | 268 } |
| 269 action modrm_pure_index { | 269 action modrm_pure_index { |
| 270 SET_DISP_TYPE(DISPNONE); | 270 SET_DISPLACEMENT_FORMAT(DISPNONE); |
| 271 SET_MODRM_BASE(NO_REG); | 271 SET_MODRM_BASE(NO_REG); |
| 272 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position)]); | 272 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position)]); |
| 273 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); | 273 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); |
| 274 } | 274 } |
| 275 action modrm_parse_sib { | 275 action modrm_parse_sib { |
| 276 SET_DISP_TYPE(DISPNONE); | 276 SET_DISPLACEMENT_FORMAT(DISPNONE); |
| 277 SET_MODRM_BASE(BaseFromSIB(*current_position)); | 277 SET_MODRM_BASE(BaseFromSIB(*current_position)); |
| 278 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position)]); | 278 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position)]); |
| 279 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); | 279 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); |
| 280 } | 280 } |
| 281 }%% | 281 }%% |
| 282 | 282 |
| 283 %%{ | 283 %%{ |
| 284 machine modrm_actions_amd64; | 284 machine modrm_actions_amd64; |
| 285 | 285 |
| 286 action modrm_only_base { | 286 action modrm_only_base { |
| 287 SET_DISP_TYPE(DISPNONE); | 287 SET_DISPLACEMENT_FORMAT(DISPNONE); |
| 288 SET_MODRM_BASE(BaseFromSIB(*current_position) | | 288 SET_MODRM_BASE(BaseFromSIB(*current_position) | |
| 289 BaseExtentionFromREX(GET_REX_PREFIX()) | | 289 BaseExtentionFromREX(GET_REX_PREFIX()) | |
| 290 BaseExtentionFromVEX(GET_VEX_PREFIX2())); | 290 BaseExtentionFromVEX(GET_VEX_PREFIX2())); |
| 291 SET_MODRM_INDEX(NO_REG); | 291 SET_MODRM_INDEX(NO_REG); |
| 292 SET_MODRM_SCALE(0); | 292 SET_MODRM_SCALE(0); |
| 293 } | 293 } |
| 294 action modrm_base_disp { | 294 action modrm_base_disp { |
| 295 SET_MODRM_BASE(BaseFromSIB(*current_position) | | 295 SET_MODRM_BASE(BaseFromSIB(*current_position) | |
| 296 BaseExtentionFromREX(GET_REX_PREFIX()) | | 296 BaseExtentionFromREX(GET_REX_PREFIX()) | |
| 297 BaseExtentionFromVEX(GET_VEX_PREFIX2())); | 297 BaseExtentionFromVEX(GET_VEX_PREFIX2())); |
| 298 SET_MODRM_INDEX(NO_REG); | 298 SET_MODRM_INDEX(NO_REG); |
| 299 SET_MODRM_SCALE(0); | 299 SET_MODRM_SCALE(0); |
| 300 } | 300 } |
| 301 action modrm_pure_disp { | 301 action modrm_pure_disp { |
| 302 // Case where ModRM.mod = 00 and ModRM.r/m = 101. | 302 // Case where ModRM.mod = 00 and ModRM.r/m = 101. |
| 303 // In 64-bit mode it corresponds to RIP-relative addressing. | 303 // In 64-bit mode it corresponds to RIP-relative addressing. |
| 304 SET_MODRM_BASE(REG_RIP); | 304 SET_MODRM_BASE(REG_RIP); |
| 305 SET_MODRM_INDEX(NO_REG); | 305 SET_MODRM_INDEX(NO_REG); |
| 306 SET_MODRM_SCALE(0); | 306 SET_MODRM_SCALE(0); |
| 307 } | 307 } |
| 308 action modrm_pure_index { | 308 action modrm_pure_index { |
| 309 SET_DISP_TYPE(DISPNONE); | 309 SET_DISPLACEMENT_FORMAT(DISPNONE); |
| 310 SET_MODRM_BASE(NO_REG); | 310 SET_MODRM_BASE(NO_REG); |
| 311 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position) | | 311 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position) | |
| 312 IndexExtentionFromREX(GET_REX_PREFIX()) | | 312 IndexExtentionFromREX(GET_REX_PREFIX()) | |
| 313 IndexExtentionFromVEX(GET_VEX_PREFIX2())]); | 313 IndexExtentionFromVEX(GET_VEX_PREFIX2())]); |
| 314 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); | 314 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); |
| 315 } | 315 } |
| 316 action modrm_parse_sib { | 316 action modrm_parse_sib { |
| 317 SET_DISP_TYPE(DISPNONE); | 317 SET_DISPLACEMENT_FORMAT(DISPNONE); |
| 318 SET_MODRM_BASE(BaseFromSIB(*current_position) | | 318 SET_MODRM_BASE(BaseFromSIB(*current_position) | |
| 319 BaseExtentionFromREX(GET_REX_PREFIX()) | | 319 BaseExtentionFromREX(GET_REX_PREFIX()) | |
| 320 BaseExtentionFromVEX(GET_VEX_PREFIX2())); | 320 BaseExtentionFromVEX(GET_VEX_PREFIX2())); |
| 321 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position) | | 321 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position) | |
| 322 IndexExtentionFromREX(GET_REX_PREFIX()) | | 322 IndexExtentionFromREX(GET_REX_PREFIX()) | |
| 323 IndexExtentionFromVEX(GET_VEX_PREFIX2())]); | 323 IndexExtentionFromVEX(GET_VEX_PREFIX2())]); |
| 324 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); | 324 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); |
| 325 } | 325 } |
| 326 }%% | 326 }%% |
| 327 | 327 |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 SET_OPERAND_NAME(3, RMFromModRM(*current_position) | | 649 SET_OPERAND_NAME(3, RMFromModRM(*current_position) | |
| 650 BaseExtentionFromREX(GET_REX_PREFIX()) | | 650 BaseExtentionFromREX(GET_REX_PREFIX()) | |
| 651 BaseExtentionFromVEX(GET_VEX_PREFIX2())); | 651 BaseExtentionFromVEX(GET_VEX_PREFIX2())); |
| 652 } | 652 } |
| 653 }%% | 653 }%% |
| 654 | 654 |
| 655 %%{ | 655 %%{ |
| 656 machine displacement_fields_parsing; | 656 machine displacement_fields_parsing; |
| 657 | 657 |
| 658 action disp8_operand { | 658 action disp8_operand { |
| 659 SET_DISP_TYPE(DISP8); | 659 SET_DISPLACEMENT_FORMAT(DISP8); |
| 660 SET_DISP_PTR(current_position); | 660 SET_DISPLACEMENT_POINTER(current_position); |
| 661 } | 661 } |
| 662 action disp32_operand { | 662 action disp32_operand { |
| 663 SET_DISP_TYPE(DISP32); | 663 SET_DISPLACEMENT_FORMAT(DISP32); |
| 664 SET_DISP_PTR(current_position - 3); | 664 SET_DISPLACEMENT_POINTER(current_position - 3); |
| 665 } | 665 } |
| 666 action disp64_operand { | 666 action disp64_operand { |
| 667 SET_DISP_TYPE(DISP64); | 667 SET_DISPLACEMENT_FORMAT(DISP64); |
| 668 SET_DISP_PTR(current_position - 7); | 668 SET_DISPLACEMENT_POINTER(current_position - 7); |
| 669 } | 669 } |
| 670 | 670 |
| 671 # This action is used to mark transitions corresponding to immediates, | 671 # This action is used to mark transitions corresponding to immediates, |
| 672 # displacements and relative jump targets - stuff that we don't have to | 672 # displacements and relative jump targets - stuff that we don't have to |
| 673 # enumerate in enumeration tests. | 673 # enumerate in enumeration tests. |
| 674 # TODO(shcherbina): find appropriate place for this action. | 674 # TODO(shcherbina): find appropriate place for this action. |
| 675 action any_byte {} | 675 action any_byte {} |
| 676 | 676 |
| 677 disp8 = any @disp8_operand $any_byte; | 677 disp8 = any @disp8_operand $any_byte; |
| 678 disp32 = any{4} @disp32_operand $any_byte; | 678 disp32 = any{4} @disp32_operand $any_byte; |
| 679 disp64 = any{8} @disp64_operand $any_byte; | 679 disp64 = any{8} @disp64_operand $any_byte; |
| 680 }%% | 680 }%% |
| 681 | 681 |
| 682 %%{ | 682 %%{ |
| 683 machine immediate_fields_parsing; | 683 machine immediate_fields_parsing; |
| 684 | 684 |
| 685 action imm2_operand { | 685 action imm2_operand { |
| 686 SET_IMM_TYPE(IMM2); | 686 SET_IMMEDIATE_FORMAT(IMM2); |
| 687 SET_IMM_PTR(current_position); | 687 SET_IMMEDIATE_POINTER(current_position); |
| 688 } | 688 } |
| 689 action imm8_operand { | 689 action imm8_operand { |
| 690 SET_IMM_TYPE(IMM8); | 690 SET_IMMEDIATE_FORMAT(IMM8); |
| 691 SET_IMM_PTR(current_position); | 691 SET_IMMEDIATE_POINTER(current_position); |
| 692 } | 692 } |
| 693 action imm8_second_operand { | 693 action imm8_second_operand { |
| 694 SET_IMM2_TYPE(IMM8); | 694 SET_SECOND_IMMEDIATE_FORMAT(IMM8); |
| 695 SET_IMM2_PTR(current_position); | 695 SET_SECOND_IMMEDIATE_POINTER(current_position); |
| 696 } | 696 } |
| 697 action imm16_operand { | 697 action imm16_operand { |
| 698 SET_IMM_TYPE(IMM16); | 698 SET_IMMEDIATE_FORMAT(IMM16); |
| 699 SET_IMM_PTR(current_position - 1); | 699 SET_IMMEDIATE_POINTER(current_position - 1); |
| 700 } | 700 } |
| 701 action imm16_second_operand { | 701 action imm16_second_operand { |
| 702 SET_IMM2_TYPE(IMM16); | 702 SET_SECOND_IMMEDIATE_FORMAT(IMM16); |
| 703 SET_IMM2_PTR(current_position - 1); | 703 SET_SECOND_IMMEDIATE_POINTER(current_position - 1); |
| 704 } | 704 } |
| 705 action imm32_operand { | 705 action imm32_operand { |
| 706 SET_IMM_TYPE(IMM32); | 706 SET_IMMEDIATE_FORMAT(IMM32); |
| 707 SET_IMM_PTR(current_position - 3); | 707 SET_IMMEDIATE_POINTER(current_position - 3); |
| 708 } | 708 } |
| 709 action imm32_second_operand { | 709 action imm32_second_operand { |
| 710 SET_IMM2_TYPE(IMM32); | 710 SET_SECOND_IMMEDIATE_FORMAT(IMM32); |
| 711 SET_IMM2_PTR(current_position - 3); | 711 SET_SECOND_IMMEDIATE_POINTER(current_position - 3); |
| 712 } | 712 } |
| 713 action imm64_operand { | 713 action imm64_operand { |
| 714 SET_IMM_TYPE(IMM64); | 714 SET_IMMEDIATE_FORMAT(IMM64); |
| 715 SET_IMM_PTR(current_position - 7); | 715 SET_IMMEDIATE_POINTER(current_position - 7); |
| 716 } | 716 } |
| 717 action imm64_second_operand { | 717 action imm64_second_operand { |
| 718 SET_IMM2_TYPE(IMM64); | 718 SET_SECOND_IMMEDIATE_FORMAT(IMM64); |
| 719 SET_IMM2_PTR(current_position - 7); | 719 SET_SECOND_IMMEDIATE_POINTER(current_position - 7); |
| 720 } | 720 } |
| 721 | 721 |
| 722 imm8 = any @imm8_operand $any_byte; | 722 imm8 = any @imm8_operand $any_byte; |
| 723 imm16 = any{2} @imm16_operand $any_byte; | 723 imm16 = any{2} @imm16_operand $any_byte; |
| 724 imm32 = any{4} @imm32_operand $any_byte; | 724 imm32 = any{4} @imm32_operand $any_byte; |
| 725 imm64 = any{8} @imm64_operand $any_byte; | 725 imm64 = any{8} @imm64_operand $any_byte; |
| 726 imm8n2 = any @imm8_second_operand $any_byte; | 726 imm8n2 = any @imm8_second_operand $any_byte; |
| 727 imm16n2 = any{2} @imm16_second_operand $any_byte; | 727 imm16n2 = any{2} @imm16_second_operand $any_byte; |
| 728 }%% | 728 }%% |
| 729 | 729 |
| 730 %%{ | 730 %%{ |
| 731 machine relative_fields_decoder_actions; | 731 machine relative_fields_decoder_actions; |
| 732 | 732 |
| 733 action rel8_operand { | 733 action rel8_operand { |
| 734 SET_MODRM_BASE(REG_RIP); | 734 SET_MODRM_BASE(REG_RIP); |
| 735 SET_MODRM_INDEX(NO_REG); | 735 SET_MODRM_INDEX(NO_REG); |
| 736 SET_MODRM_SCALE(0); | 736 SET_MODRM_SCALE(0); |
| 737 SET_DISP_TYPE(DISP8); | 737 SET_DISPLACEMENT_FORMAT(DISP8); |
| 738 SET_DISP_PTR(current_position); | 738 SET_DISPLACEMENT_POINTER(current_position); |
| 739 } | 739 } |
| 740 action rel16_operand { | 740 action rel16_operand { |
| 741 SET_MODRM_BASE(REG_RIP); | 741 SET_MODRM_BASE(REG_RIP); |
| 742 SET_MODRM_INDEX(NO_REG); | 742 SET_MODRM_INDEX(NO_REG); |
| 743 SET_MODRM_SCALE(0); | 743 SET_MODRM_SCALE(0); |
| 744 SET_DISP_TYPE(DISP16); | 744 SET_DISPLACEMENT_FORMAT(DISP16); |
| 745 SET_DISP_PTR(current_position - 1); | 745 SET_DISPLACEMENT_POINTER(current_position - 1); |
| 746 } | 746 } |
| 747 action rel32_operand { | 747 action rel32_operand { |
| 748 SET_MODRM_BASE(REG_RIP); | 748 SET_MODRM_BASE(REG_RIP); |
| 749 SET_MODRM_INDEX(NO_REG); | 749 SET_MODRM_INDEX(NO_REG); |
| 750 SET_MODRM_SCALE(0); | 750 SET_MODRM_SCALE(0); |
| 751 SET_DISP_TYPE(DISP32); | 751 SET_DISPLACEMENT_FORMAT(DISP32); |
| 752 SET_DISP_PTR(current_position - 3); | 752 SET_DISPLACEMENT_POINTER(current_position - 3); |
| 753 } | 753 } |
| 754 }%% | 754 }%% |
| 755 | 755 |
| 756 %%{ | 756 %%{ |
| 757 machine relative_fields_validator_actions; | 757 machine relative_fields_validator_actions; |
| 758 | 758 |
| 759 # rel8 actions are used in relative jumps with 8-bit offset. | 759 # rel8 actions are used in relative jumps with 8-bit offset. |
| 760 action rel8_operand { | 760 action rel8_operand { |
| 761 Rel8Operand(current_position + 1, data, jump_dests, size, | 761 Rel8Operand(current_position + 1, codeblock, jump_dests, size, |
| 762 &instruction_info_collected); | 762 &instruction_info_collected); |
| 763 } | 763 } |
| 764 | 764 |
| 765 # rel16 actions are used in relative jumps with 16-bit offset. | 765 # rel16 actions are used in relative jumps with 16-bit offset. |
| 766 # Such instructions should not be included in the validator's DFA, but we can | 766 # Such instructions should not be included in the validator's DFA, but we can |
| 767 # not just exclude them because they are refenced in relative_fields_parsing | 767 # not just exclude them because they are refenced in relative_fields_parsing |
| 768 # ragel machine. Ensure compilations error in case of accidental usage. | 768 # ragel machine. Ensure compilations error in case of accidental usage. |
| 769 action rel16_operand { | 769 action rel16_operand { |
| 770 #error rel16_operand should never be used in nacl | 770 #error rel16_operand should never be used in nacl |
| 771 } | 771 } |
| 772 | 772 |
| 773 # rel32 actions are used in relative calls and jumps with 32-bit offset. | 773 # rel32 actions are used in relative calls and jumps with 32-bit offset. |
| 774 action rel32_operand { | 774 action rel32_operand { |
| 775 Rel32Operand(current_position + 1, data, jump_dests, size, | 775 Rel32Operand(current_position + 1, codeblock, jump_dests, size, |
| 776 &instruction_info_collected); | 776 &instruction_info_collected); |
| 777 } | 777 } |
| 778 |
| 779 # Action which marks last byte as not immediate. Most 3DNow! instructions, |
| 780 # some AVX and XOP instructions have this property. |
| 781 # |
| 782 # This action is referenced by decode_x86_32 ragel machine in [autogenerated] |
| 783 # "validator_x86_32_instruction.rl" file. |
| 784 action last_byte_is_not_immediate { |
| 785 instruction_info_collected |= LAST_BYTE_IS_NOT_IMMEDIATE; |
| 786 } |
| 778 }%% | 787 }%% |
| 779 | 788 |
| 780 %%{ | 789 %%{ |
| 781 machine relative_fields_parsing; | 790 machine relative_fields_parsing; |
| 782 | 791 |
| 783 rel8 = any @rel8_operand $any_byte; | 792 rel8 = any @rel8_operand $any_byte; |
| 784 rel16 = any{2} @rel16_operand $any_byte; | 793 rel16 = any{2} @rel16_operand $any_byte; |
| 785 rel32 = any{4} @rel32_operand $any_byte; | 794 rel32 = any{4} @rel32_operand $any_byte; |
| 786 }%% | 795 }%% |
| 787 | 796 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 action att_show_name_suffix_b { SET_ATT_INSTRUCTION_SUFFIX("b"); } | 852 action att_show_name_suffix_b { SET_ATT_INSTRUCTION_SUFFIX("b"); } |
| 844 action att_show_name_suffix_l { SET_ATT_INSTRUCTION_SUFFIX("l"); } | 853 action att_show_name_suffix_l { SET_ATT_INSTRUCTION_SUFFIX("l"); } |
| 845 action att_show_name_suffix_ll { SET_ATT_INSTRUCTION_SUFFIX("ll"); } | 854 action att_show_name_suffix_ll { SET_ATT_INSTRUCTION_SUFFIX("ll"); } |
| 846 action att_show_name_suffix_t { SET_ATT_INSTRUCTION_SUFFIX("t"); } | 855 action att_show_name_suffix_t { SET_ATT_INSTRUCTION_SUFFIX("t"); } |
| 847 action att_show_name_suffix_s { SET_ATT_INSTRUCTION_SUFFIX("s"); } | 856 action att_show_name_suffix_s { SET_ATT_INSTRUCTION_SUFFIX("s"); } |
| 848 action att_show_name_suffix_q { SET_ATT_INSTRUCTION_SUFFIX("q"); } | 857 action att_show_name_suffix_q { SET_ATT_INSTRUCTION_SUFFIX("q"); } |
| 849 action att_show_name_suffix_w { SET_ATT_INSTRUCTION_SUFFIX("w"); } | 858 action att_show_name_suffix_w { SET_ATT_INSTRUCTION_SUFFIX("w"); } |
| 850 action att_show_name_suffix_x { SET_ATT_INSTRUCTION_SUFFIX("x"); } | 859 action att_show_name_suffix_x { SET_ATT_INSTRUCTION_SUFFIX("x"); } |
| 851 action att_show_name_suffix_y { SET_ATT_INSTRUCTION_SUFFIX("y"); } | 860 action att_show_name_suffix_y { SET_ATT_INSTRUCTION_SUFFIX("y"); } |
| 852 }%% | 861 }%% |
| OLD | NEW |