Index: third_party/crashpad/crashpad/snapshot/cpu_context.cc |
diff --git a/third_party/crashpad/crashpad/snapshot/cpu_context.cc b/third_party/crashpad/crashpad/snapshot/cpu_context.cc |
index c11a031b11caf2a17d0e40ee2948588faf33ef2c..c3887a2c36bd61858a1ab88ead27bb5b14578165 100644 |
--- a/third_party/crashpad/crashpad/snapshot/cpu_context.cc |
+++ b/third_party/crashpad/crashpad/snapshot/cpu_context.cc |
@@ -14,23 +14,84 @@ |
#include "snapshot/cpu_context.h" |
+#include <string.h> |
+ |
#include "base/logging.h" |
+#include "base/macros.h" |
#include "util/misc/implicit_cast.h" |
namespace crashpad { |
+namespace { |
+ |
+// Sanity-check complex structures to ensure interoperability. |
+static_assert(sizeof(CPUContextX86::Fsave) == 108, "CPUContextX86::Fsave size"); |
+static_assert(sizeof(CPUContextX86::Fxsave) == 512, |
+ "CPUContextX86::Fxsave size"); |
+static_assert(sizeof(CPUContextX86_64::Fxsave) == 512, |
+ "CPUContextX86_64::Fxsave size"); |
+ |
+enum { |
+ kX87TagValid = 0, |
+ kX87TagZero, |
+ kX87TagSpecial, |
+ kX87TagEmpty, |
+}; |
+ |
+} // namespace |
+ |
+// static |
+void CPUContextX86::FxsaveToFsave(const Fxsave& fxsave, Fsave* fsave) { |
+ fsave->fcw = fxsave.fcw; |
+ fsave->reserved_1 = 0; |
+ fsave->fsw = fxsave.fsw; |
+ fsave->reserved_2 = 0; |
+ fsave->ftw = FxsaveToFsaveTagWord(fxsave.fsw, fxsave.ftw, fxsave.st_mm); |
+ fsave->reserved_3 = 0; |
+ fsave->fpu_ip = fxsave.fpu_ip; |
+ fsave->fpu_cs = fxsave.fpu_cs; |
+ fsave->fop = fxsave.fop; |
+ fsave->fpu_dp = fxsave.fpu_dp; |
+ fsave->fpu_ds = fxsave.fpu_ds; |
+ fsave->reserved_4 = 0; |
+ static_assert(arraysize(fsave->st) == arraysize(fxsave.st_mm), |
+ "FPU stack registers must be equivalent"); |
+ for (size_t index = 0; index < arraysize(fsave->st); ++index) { |
+ memcpy(fsave->st[index], fxsave.st_mm[index].st, sizeof(fsave->st[index])); |
+ } |
+} |
+ |
+// static |
+void CPUContextX86::FsaveToFxsave(const Fsave& fsave, Fxsave* fxsave) { |
+ fxsave->fcw = fsave.fcw; |
+ fxsave->fsw = fsave.fsw; |
+ fxsave->ftw = FsaveToFxsaveTagWord(fsave.ftw); |
+ fxsave->reserved_1 = 0; |
+ fxsave->fop = fsave.fop; |
+ fxsave->fpu_ip = fsave.fpu_ip; |
+ fxsave->fpu_cs = fsave.fpu_cs; |
+ fxsave->reserved_2 = 0; |
+ fxsave->fpu_dp = fsave.fpu_dp; |
+ fxsave->fpu_ds = fsave.fpu_ds; |
+ fxsave->reserved_3 = 0; |
+ fxsave->mxcsr = 0; |
+ fxsave->mxcsr_mask = 0; |
+ static_assert(arraysize(fxsave->st_mm) == arraysize(fsave.st), |
+ "FPU stack registers must be equivalent"); |
+ for (size_t index = 0; index < arraysize(fsave.st); ++index) { |
+ memcpy(fxsave->st_mm[index].st, fsave.st[index], sizeof(fsave.st[index])); |
+ memset(fxsave->st_mm[index].st_reserved, |
+ 0, |
+ sizeof(fxsave->st_mm[index].st_reserved)); |
+ } |
+ memset(fxsave->xmm, 0, sizeof(*fxsave) - offsetof(Fxsave, xmm)); |
+} |
+ |
// static |
uint16_t CPUContextX86::FxsaveToFsaveTagWord( |
uint16_t fsw, |
uint8_t fxsave_tag, |
const CPUContextX86::X87OrMMXRegister st_mm[8]) { |
- enum { |
- kX87TagValid = 0, |
- kX87TagZero, |
- kX87TagSpecial, |
- kX87TagEmpty, |
- }; |
- |
// The x87 tag word (in both abridged and full form) identifies physical |
// registers, but |st_mm| is arranged in logical stack order. In order to map |
// physical tag word bits to the logical stack registers they correspond to, |
@@ -85,6 +146,17 @@ uint16_t CPUContextX86::FxsaveToFsaveTagWord( |
return fsave_tag; |
} |
+// static |
+uint8_t CPUContextX86::FsaveToFxsaveTagWord(uint16_t fsave_tag) { |
+ uint8_t fxsave_tag = 0; |
+ for (int physical_index = 0; physical_index < 8; ++physical_index) { |
+ const uint8_t fsave_bits = (fsave_tag >> (physical_index * 2)) & 0x3; |
+ const bool fxsave_bit = fsave_bits != kX87TagEmpty; |
+ fxsave_tag |= fxsave_bit << physical_index; |
+ } |
+ return fxsave_tag; |
+} |
+ |
uint64_t CPUContext::InstructionPointer() const { |
switch (architecture) { |
case kCPUArchitectureX86: |