OLD | NEW |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 The Crashpad Authors. 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, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 #include "snapshot/cpu_context.h" | 15 #include "snapshot/cpu_context.h" |
16 | 16 |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 | 18 |
19 namespace crashpad { | 19 namespace crashpad { |
20 | 20 |
| 21 // static |
| 22 uint16_t CPUContextX86::FxsaveToFsaveTagWord( |
| 23 uint16_t fsw, |
| 24 uint8_t fxsave_tag, |
| 25 const CPUContextX86::X87OrMMXRegister st_mm[8]) { |
| 26 enum { |
| 27 kX87TagValid = 0, |
| 28 kX87TagZero, |
| 29 kX87TagSpecial, |
| 30 kX87TagEmpty, |
| 31 }; |
| 32 |
| 33 // The x87 tag word (in both abridged and full form) identifies physical |
| 34 // registers, but |st_mm| is arranged in logical stack order. In order to map |
| 35 // physical tag word bits to the logical stack registers they correspond to, |
| 36 // the “stack top” value from the x87 status word is necessary. |
| 37 int stack_top = (fsw >> 11) & 0x7; |
| 38 |
| 39 uint16_t fsave_tag = 0; |
| 40 for (int physical_index = 0; physical_index < 8; ++physical_index) { |
| 41 bool fxsave_bit = fxsave_tag & (1 << physical_index); |
| 42 uint8_t fsave_bits; |
| 43 |
| 44 if (fxsave_bit) { |
| 45 int st_index = (physical_index + 8 - stack_top) % 8; |
| 46 const CPUContextX86::X87Register& st = st_mm[st_index].st; |
| 47 |
| 48 uint32_t exponent = ((st[9] & 0x7f) << 8) | st[8]; |
| 49 if (exponent == 0x7fff) { |
| 50 // Infinity, NaN, pseudo-infinity, or pseudo-NaN. If it was important to |
| 51 // distinguish between these, the J bit and the M bit (the most |
| 52 // significant bit of |fraction|) could be consulted. |
| 53 fsave_bits = kX87TagSpecial; |
| 54 } else { |
| 55 // The integer bit the “J bit”. |
| 56 bool integer_bit = st[7] & 0x80; |
| 57 if (exponent == 0) { |
| 58 uint64_t fraction = ((static_cast<uint64_t>(st[7]) & 0x7f) << 56) | |
| 59 (static_cast<uint64_t>(st[6]) << 48) | |
| 60 (static_cast<uint64_t>(st[5]) << 40) | |
| 61 (static_cast<uint64_t>(st[4]) << 32) | |
| 62 (static_cast<uint32_t>(st[3]) << 24) | |
| 63 (st[2] << 16) | (st[1] << 8) | st[0]; |
| 64 if (!integer_bit && fraction == 0) { |
| 65 fsave_bits = kX87TagZero; |
| 66 } else { |
| 67 // Denormal (if the J bit is clear) or pseudo-denormal. |
| 68 fsave_bits = kX87TagSpecial; |
| 69 } |
| 70 } else if (integer_bit) { |
| 71 fsave_bits = kX87TagValid; |
| 72 } else { |
| 73 // Unnormal. |
| 74 fsave_bits = kX87TagSpecial; |
| 75 } |
| 76 } |
| 77 } else { |
| 78 fsave_bits = kX87TagEmpty; |
| 79 } |
| 80 |
| 81 fsave_tag |= (fsave_bits << (physical_index * 2)); |
| 82 } |
| 83 |
| 84 return fsave_tag; |
| 85 } |
| 86 |
21 uint64_t CPUContext::InstructionPointer() const { | 87 uint64_t CPUContext::InstructionPointer() const { |
22 switch (architecture) { | 88 switch (architecture) { |
23 case kCPUArchitectureX86: | 89 case kCPUArchitectureX86: |
24 return x86->eip; | 90 return x86->eip; |
25 case kCPUArchitectureX86_64: | 91 case kCPUArchitectureX86_64: |
26 return x86_64->rip; | 92 return x86_64->rip; |
27 default: | 93 default: |
28 NOTREACHED(); | 94 NOTREACHED(); |
29 return -1; | 95 return -1; |
30 } | 96 } |
31 } | 97 } |
32 | 98 |
33 } // namespace crashpad | 99 } // namespace crashpad |
OLD | NEW |