Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: syzygy/core/disassembler_util.cc

Issue 2841863003: Improve the decoding of the VEX encoded instructions. (Closed)
Patch Set: Use a constant. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | syzygy/core/disassembler_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 Google Inc. All Rights Reserved. 1 // Copyright 2012 Google Inc. All Rights Reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 22 matching lines...) Expand all
33 // | 1 1 0 0 0 1 0 0 | 33 // | 1 1 0 0 0 1 0 0 |
34 // +---+---+---+---+---+---+---+---+ 34 // +---+---+---+---+---+---+---+---+
35 // - Second byte: 35 // - Second byte:
36 // +---+---+---+---+---+---+---+---+ 36 // +---+---+---+---+---+---+---+---+
37 // |~R |~X |~B | map_select | 37 // |~R |~X |~B | map_select |
38 // +---+---+---+---+---+---+---+---+ 38 // +---+---+---+---+---+---+---+---+
39 // - Third byte: 39 // - Third byte:
40 // +---+---+---+---+---+---+---+---+ 40 // +---+---+---+---+---+---+---+---+
41 // |W/E| ~vvvv | L | pp | 41 // |W/E| ~vvvv | L | pp |
42 // +---+---+---+---+---+---+---+---+ 42 // +---+---+---+---+---+---+---+---+
43 // - Fourth byte: The opcode for this instruction. 43 // - Fourth byte: The opcode for this instruction.
chrisha 2017/04/26 15:09:10 Update the comment? Or is this still up to date?
44 // 44 //
45 // |map_select| Indicates the opcode map that should be used for this 45 // |map_select| Indicates the opcode map that should be used for this
46 // instruction. 46 // instruction.
47 // 47 //
48 // See http://wiki.osdev.org/X86-64_Instruction_Encoding#Three_byte_VEX_escape_p refix 48 // See http://wiki.osdev.org/X86-64_Instruction_Encoding#Three_byte_VEX_escape_p refix
49 // for more details. 49 // for more details.
50 //
51 // NOTE: Most of these instructions can have a variable length because they use
52 // ModRM:r/m, we only support the variants that have been observed in Chrome.
50 size_t Get3ByteVexEncodedInstructionSize(_CodeInfo* ci) { 53 size_t Get3ByteVexEncodedInstructionSize(_CodeInfo* ci) {
chrisha 2017/04/26 15:09:10 This is no longer just 3byte VEX instructions? Or
54 const uint8_t kModRMMask = 0xC0;
55
51 DCHECK_EQ(0xC4, ci->code[0]); 56 DCHECK_EQ(0xC4, ci->code[0]);
52 // Switch case based on the opcode map used by this instruction. 57 // Switch case based on the opcode map used by this instruction.
53 switch (ci->code[1] & 0x1F) { 58 switch (ci->code[1] & 0x1F) {
54 case 0x02: { 59 case 0x02: {
55 switch (ci->code[3]) { 60 switch (ci->code[3]) {
56 case 0x13: return 5; // vcvtps2ps 61 case 0x13: return 5; // vcvtph2ps
57 case 0x18: return 5; // vbroadcastss 62 case 0x18: { // vbroadcastss
58 case 0x36: return 5; // vpermd 63 CHECK((ci->code[4] & kModRMMask) != 0) <<
huangs 2017/04/25 22:14:20 Perhaps this should be CHECK((ci->code[4] & kMod
59 case 0x58: return 6; // vpbroadcastd 64 "Unsupported variant of the vbroadcastss instruction";
65 return 5;
66 }
67 case 0x36: { // vpermd
68 CHECK((ci->code[4] & kModRMMask) != 0) <<
69 "Unsupported variant of the vpermd instruction";
70 return 5;
71 }
72 case 0x58: // vpbroadcastb
73 case 0x78: { // vpbroadcastd
74 if ((ci->code[4] & kModRMMask) != kModRMMask) {
75 return 6;
huangs 2017/04/25 22:14:20 Cannot guarantee 6, due to possibility of SIB. For
76 } else {
77 return 5;
78 }
79 }
60 case 0x5A: return 6; // vbroadcasti128 80 case 0x5A: return 6; // vbroadcasti128
61 case 0x78: return 5; // vpbroadcastb 81 case 0x8C: { // vpmaskmovd
62 case 0x8C: return 5; // vpmaskmovd 82 CHECK((ci->code[4] & kModRMMask) == 0) <<
63 case 0x8E: return 5; // vpmaskmovd 83 "Unsupported variant of the vpmaskmovd instruction";
64 case 0x90: return 6; // vpgatherdd 84 return 5;
85 }
86 case 0x90: { // vpgatherdd
87 CHECK((ci->code[4] & kModRMMask) == 0) <<
88 "Unsupported variant of the vpgatherdd instruction";
89 return 6;
90 }
65 default: 91 default:
66 break; 92 break;
67 } 93 }
68 break; 94 break;
69 } 95 }
70 case 0x03: { 96 case 0x03: {
71 switch (ci->code[3]) { 97 switch (ci->code[3]) {
72 case 0x00: return 6; // vpermq 98 case 0x00: return 6; // vpermq
73 case 0x1D: return 6; // vcvtps2ph 99 case 0x1D: return 6; // vcvtps2ph
74 case 0x38: return 7; // vinserti128 100 case 0x38: { // vinserti128
75 case 0x39: return 6; // vextracti128 101 CHECK((ci->code[4] & kModRMMask) == 0) <<
102 "Unsupported variant of the vinserti128 instruction";
103 return 7;
104 }
105 case 0x39: { // vextracti128
106 CHECK((ci->code[4] & kModRMMask) != 0) <<
107 "Unsupported variant of the vextracti128 instruction";
108 return 6;
109 }
76 default: break; 110 default: break;
77 } 111 }
78 break; 112 break;
79 } 113 }
80 default: 114 default:
81 break; 115 break;
82 } 116 }
83 117
84 // Print the instructions that we haven't been able to decompose in a format 118 // Print the instructions that we haven't been able to decompose in a format
85 // that can easily be pasted into ODA (https://onlinedisassembler.com/). 119 // that can easily be pasted into ODA (https://onlinedisassembler.com/).
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 CHECK_EQ(O_NONE, result->ops[3].type); 177 CHECK_EQ(O_NONE, result->ops[3].type);
144 178
145 --result->addr; 179 --result->addr;
146 ++result->size; 180 ++result->size;
147 181
148 *used_instructions_count = 1; 182 *used_instructions_count = 1;
149 *ret = DECRES_SUCCESS; 183 *ret = DECRES_SUCCESS;
150 184
151 return true; 185 return true;
152 } 186 }
187 } else if (ci->code[0] == 0xC4) {
188 size = Get3ByteVexEncodedInstructionSize(ci);
153 } 189 }
154 190
155 if (ci->code[0] == 0xC4)
156 size = Get3ByteVexEncodedInstructionSize(ci);
157
158 if (size == 0) 191 if (size == 0)
159 return false; 192 return false;
160 193
161 // We set the bare minimum properties that are required for any 194 // We set the bare minimum properties that are required for any
162 // subsequent processing that we perform. 195 // subsequent processing that we perform.
163 196
164 *used_instructions_count = 1; 197 *used_instructions_count = 1;
165 198
166 ::memset(result, 0, sizeof(result[0])); 199 ::memset(result, 0, sizeof(result[0]));
167 result[0].addr = ci->codeOffset; 200 result[0].addr = ci->codeOffset;
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 477
445 default: return assm::kRegisterNone; 478 default: return assm::kRegisterNone;
446 } 479 }
447 } 480 }
448 481
449 const Register& GetRegister(uint32_t distorm_reg_type) { 482 const Register& GetRegister(uint32_t distorm_reg_type) {
450 return Register::Get(GetRegisterId(distorm_reg_type)); 483 return Register::Get(GetRegisterId(distorm_reg_type));
451 } 484 }
452 485
453 } // namespace core 486 } // namespace core
OLDNEW
« no previous file with comments | « no previous file | syzygy/core/disassembler_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698