OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |