| Index: third_party/crashpad/crashpad/minidump/minidump_context_writer.cc
|
| diff --git a/third_party/crashpad/crashpad/minidump/minidump_context_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_context_writer.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fef1af31d2819815c1d10d834a9bf0e610f5f8cb
|
| --- /dev/null
|
| +++ b/third_party/crashpad/crashpad/minidump/minidump_context_writer.cc
|
| @@ -0,0 +1,215 @@
|
| +// Copyright 2014 The Crashpad Authors. All rights reserved.
|
| +//
|
| +// Licensed under the Apache License, Version 2.0 (the "License");
|
| +// you may not use this file except in compliance with the License.
|
| +// You may obtain a copy of the License at
|
| +//
|
| +// http://www.apache.org/licenses/LICENSE-2.0
|
| +//
|
| +// Unless required by applicable law or agreed to in writing, software
|
| +// distributed under the License is distributed on an "AS IS" BASIS,
|
| +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| +// See the License for the specific language governing permissions and
|
| +// limitations under the License.
|
| +
|
| +#include "minidump/minidump_context_writer.h"
|
| +
|
| +#include <string.h>
|
| +
|
| +#include "base/compiler_specific.h"
|
| +#include "base/logging.h"
|
| +#include "snapshot/cpu_context.h"
|
| +#include "util/file/file_writer.h"
|
| +
|
| +namespace crashpad {
|
| +
|
| +MinidumpContextWriter::~MinidumpContextWriter() {
|
| +}
|
| +
|
| +// static
|
| +scoped_ptr<MinidumpContextWriter> MinidumpContextWriter::CreateFromSnapshot(
|
| + const CPUContext* context_snapshot) {
|
| + scoped_ptr<MinidumpContextWriter> context;
|
| +
|
| + switch (context_snapshot->architecture) {
|
| + case kCPUArchitectureX86: {
|
| + MinidumpContextX86Writer* context_x86 = new MinidumpContextX86Writer();
|
| + context.reset(context_x86);
|
| + context_x86->InitializeFromSnapshot(context_snapshot->x86);
|
| + break;
|
| + }
|
| +
|
| + case kCPUArchitectureX86_64: {
|
| + MSVC_PUSH_DISABLE_WARNING(4316); // Object on heap may not be aligned.
|
| + MinidumpContextAMD64Writer* context_amd64 =
|
| + new MinidumpContextAMD64Writer();
|
| + MSVC_POP_WARNING(); // C4316
|
| + context.reset(context_amd64);
|
| + context_amd64->InitializeFromSnapshot(context_snapshot->x86_64);
|
| + break;
|
| + }
|
| +
|
| + default: {
|
| + LOG(ERROR) << "unknown context architecture "
|
| + << context_snapshot->architecture;
|
| + break;
|
| + }
|
| + }
|
| +
|
| + return context;
|
| +}
|
| +
|
| +size_t MinidumpContextWriter::SizeOfObject() {
|
| + DCHECK_GE(state(), kStateFrozen);
|
| +
|
| + return ContextSize();
|
| +}
|
| +
|
| +MinidumpContextX86Writer::MinidumpContextX86Writer()
|
| + : MinidumpContextWriter(), context_() {
|
| + context_.context_flags = kMinidumpContextX86;
|
| +}
|
| +
|
| +MinidumpContextX86Writer::~MinidumpContextX86Writer() {
|
| +}
|
| +
|
| +
|
| +void MinidumpContextX86Writer::InitializeFromSnapshot(
|
| + const CPUContextX86* context_snapshot) {
|
| + DCHECK_EQ(state(), kStateMutable);
|
| + DCHECK_EQ(context_.context_flags, kMinidumpContextX86);
|
| +
|
| + context_.context_flags = kMinidumpContextX86All;
|
| +
|
| + context_.dr0 = context_snapshot->dr0;
|
| + context_.dr1 = context_snapshot->dr1;
|
| + context_.dr2 = context_snapshot->dr2;
|
| + context_.dr3 = context_snapshot->dr3;
|
| + context_.dr6 = context_snapshot->dr6;
|
| + context_.dr7 = context_snapshot->dr7;
|
| +
|
| + // The contents of context_.float_save effectively alias everything in
|
| + // context_.fxsave that’s related to x87 FPU state. context_.float_save
|
| + // doesn’t carry state specific to SSE (or later), such as mxcsr and the xmm
|
| + // registers.
|
| + context_.float_save.control_word = context_snapshot->fxsave.fcw;
|
| + context_.float_save.status_word = context_snapshot->fxsave.fsw;
|
| + context_.float_save.tag_word =
|
| + CPUContextX86::FxsaveToFsaveTagWord(context_snapshot->fxsave.fsw,
|
| + context_snapshot->fxsave.ftw,
|
| + context_snapshot->fxsave.st_mm);
|
| + context_.float_save.error_offset = context_snapshot->fxsave.fpu_ip;
|
| + context_.float_save.error_selector = context_snapshot->fxsave.fpu_cs;
|
| + context_.float_save.data_offset = context_snapshot->fxsave.fpu_dp;
|
| + context_.float_save.data_selector = context_snapshot->fxsave.fpu_ds;
|
| +
|
| + for (size_t index = 0, offset = 0;
|
| + index < arraysize(context_snapshot->fxsave.st_mm);
|
| + offset += sizeof(context_snapshot->fxsave.st_mm[index].st), ++index) {
|
| + memcpy(&context_.float_save.register_area[offset],
|
| + &context_snapshot->fxsave.st_mm[index].st,
|
| + sizeof(context_snapshot->fxsave.st_mm[index].st));
|
| + }
|
| +
|
| + context_.gs = context_snapshot->gs;
|
| + context_.fs = context_snapshot->fs;
|
| + context_.es = context_snapshot->es;
|
| + context_.ds = context_snapshot->ds;
|
| + context_.edi = context_snapshot->edi;
|
| + context_.esi = context_snapshot->esi;
|
| + context_.ebx = context_snapshot->ebx;
|
| + context_.edx = context_snapshot->edx;
|
| + context_.ecx = context_snapshot->ecx;
|
| + context_.eax = context_snapshot->eax;
|
| + context_.ebp = context_snapshot->ebp;
|
| + context_.eip = context_snapshot->eip;
|
| + context_.cs = context_snapshot->cs;
|
| + context_.eflags = context_snapshot->eflags;
|
| + context_.esp = context_snapshot->esp;
|
| + context_.ss = context_snapshot->ss;
|
| +
|
| + // This is effectively a memcpy() of a big structure.
|
| + context_.fxsave = context_snapshot->fxsave;
|
| +}
|
| +
|
| +bool MinidumpContextX86Writer::WriteObject(FileWriterInterface* file_writer) {
|
| + DCHECK_EQ(state(), kStateWritable);
|
| +
|
| + return file_writer->Write(&context_, sizeof(context_));
|
| +}
|
| +
|
| +size_t MinidumpContextX86Writer::ContextSize() const {
|
| + DCHECK_GE(state(), kStateFrozen);
|
| +
|
| + return sizeof(context_);
|
| +}
|
| +
|
| +MinidumpContextAMD64Writer::MinidumpContextAMD64Writer()
|
| + : MinidumpContextWriter(), context_() {
|
| + context_.context_flags = kMinidumpContextAMD64;
|
| +}
|
| +
|
| +MinidumpContextAMD64Writer::~MinidumpContextAMD64Writer() {
|
| +}
|
| +
|
| +void MinidumpContextAMD64Writer::InitializeFromSnapshot(
|
| + const CPUContextX86_64* context_snapshot) {
|
| + DCHECK_EQ(state(), kStateMutable);
|
| + DCHECK_EQ(context_.context_flags, kMinidumpContextAMD64);
|
| +
|
| + context_.context_flags = kMinidumpContextAMD64All;
|
| +
|
| + context_.mx_csr = context_snapshot->fxsave.mxcsr;
|
| + context_.cs = context_snapshot->cs;
|
| + context_.fs = context_snapshot->fs;
|
| + context_.gs = context_snapshot->gs;
|
| + // The top 32 bits of rflags are reserved/unused.
|
| + context_.eflags = static_cast<uint32_t>(context_snapshot->rflags);
|
| + context_.dr0 = context_snapshot->dr0;
|
| + context_.dr1 = context_snapshot->dr1;
|
| + context_.dr2 = context_snapshot->dr2;
|
| + context_.dr3 = context_snapshot->dr3;
|
| + context_.dr6 = context_snapshot->dr6;
|
| + context_.dr7 = context_snapshot->dr7;
|
| + context_.rax = context_snapshot->rax;
|
| + context_.rcx = context_snapshot->rcx;
|
| + context_.rdx = context_snapshot->rdx;
|
| + context_.rbx = context_snapshot->rbx;
|
| + context_.rsp = context_snapshot->rsp;
|
| + context_.rbp = context_snapshot->rbp;
|
| + context_.rsi = context_snapshot->rsi;
|
| + context_.rdi = context_snapshot->rdi;
|
| + context_.r8 = context_snapshot->r8;
|
| + context_.r9 = context_snapshot->r9;
|
| + context_.r10 = context_snapshot->r10;
|
| + context_.r11 = context_snapshot->r11;
|
| + context_.r12 = context_snapshot->r12;
|
| + context_.r13 = context_snapshot->r13;
|
| + context_.r14 = context_snapshot->r14;
|
| + context_.r15 = context_snapshot->r15;
|
| + context_.rip = context_snapshot->rip;
|
| +
|
| + // This is effectively a memcpy() of a big structure.
|
| + context_.fxsave = context_snapshot->fxsave;
|
| +}
|
| +
|
| +size_t MinidumpContextAMD64Writer::Alignment() {
|
| + DCHECK_GE(state(), kStateFrozen);
|
| +
|
| + // Match the alignment of MinidumpContextAMD64.
|
| + return 16;
|
| +}
|
| +
|
| +bool MinidumpContextAMD64Writer::WriteObject(FileWriterInterface* file_writer) {
|
| + DCHECK_EQ(state(), kStateWritable);
|
| +
|
| + return file_writer->Write(&context_, sizeof(context_));
|
| +}
|
| +
|
| +size_t MinidumpContextAMD64Writer::ContextSize() const {
|
| + DCHECK_GE(state(), kStateFrozen);
|
| +
|
| + return sizeof(context_);
|
| +}
|
| +
|
| +} // namespace crashpad
|
|
|