Chromium Code Reviews| 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 |