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 "minidump/minidump_context_writer.h" | 15 #include "minidump/minidump_context_writer.h" |
16 | 16 |
| 17 #include <string.h> |
| 18 |
17 #include "base/logging.h" | 19 #include "base/logging.h" |
| 20 #include "snapshot/cpu_context.h" |
18 #include "util/file/file_writer.h" | 21 #include "util/file/file_writer.h" |
19 | 22 |
20 namespace crashpad { | 23 namespace crashpad { |
21 | 24 |
22 MinidumpContextWriter::~MinidumpContextWriter() { | 25 MinidumpContextWriter::~MinidumpContextWriter() { |
23 } | 26 } |
24 | 27 |
| 28 // static |
| 29 scoped_ptr<MinidumpContextWriter> MinidumpContextWriter::CreateFromSnapshot( |
| 30 const CPUContext* context_snapshot) { |
| 31 scoped_ptr<MinidumpContextWriter> context; |
| 32 |
| 33 switch (context_snapshot->architecture) { |
| 34 case kCPUArchitectureX86: { |
| 35 MinidumpContextX86Writer* context_x86 = new MinidumpContextX86Writer(); |
| 36 context.reset(context_x86); |
| 37 context_x86->InitializeFromSnapshot(context_snapshot->x86); |
| 38 break; |
| 39 } |
| 40 |
| 41 case kCPUArchitectureX86_64: { |
| 42 MinidumpContextAMD64Writer* context_amd64 = |
| 43 new MinidumpContextAMD64Writer(); |
| 44 context.reset(context_amd64); |
| 45 context_amd64->InitializeFromSnapshot(context_snapshot->x86_64); |
| 46 break; |
| 47 } |
| 48 |
| 49 default: { |
| 50 LOG(ERROR) << "unknown context architecture " |
| 51 << context_snapshot->architecture; |
| 52 break; |
| 53 } |
| 54 } |
| 55 |
| 56 return context; |
| 57 } |
| 58 |
25 size_t MinidumpContextWriter::SizeOfObject() { | 59 size_t MinidumpContextWriter::SizeOfObject() { |
26 DCHECK_GE(state(), kStateFrozen); | 60 DCHECK_GE(state(), kStateFrozen); |
27 | 61 |
28 return ContextSize(); | 62 return ContextSize(); |
29 } | 63 } |
30 | 64 |
31 MinidumpContextX86Writer::MinidumpContextX86Writer() | 65 MinidumpContextX86Writer::MinidumpContextX86Writer() |
32 : MinidumpContextWriter(), context_() { | 66 : MinidumpContextWriter(), context_() { |
33 context_.context_flags = kMinidumpContextX86; | 67 context_.context_flags = kMinidumpContextX86; |
34 } | 68 } |
35 | 69 |
36 MinidumpContextX86Writer::~MinidumpContextX86Writer() { | 70 MinidumpContextX86Writer::~MinidumpContextX86Writer() { |
37 } | 71 } |
38 | 72 |
| 73 |
| 74 void MinidumpContextX86Writer::InitializeFromSnapshot( |
| 75 const CPUContextX86* context_snapshot) { |
| 76 DCHECK_EQ(state(), kStateMutable); |
| 77 DCHECK_EQ(context_.context_flags, kMinidumpContextX86); |
| 78 |
| 79 context_.context_flags = kMinidumpContextX86All; |
| 80 |
| 81 context_.dr0 = context_snapshot->dr0; |
| 82 context_.dr1 = context_snapshot->dr1; |
| 83 context_.dr2 = context_snapshot->dr2; |
| 84 context_.dr3 = context_snapshot->dr3; |
| 85 context_.dr6 = context_snapshot->dr6; |
| 86 context_.dr7 = context_snapshot->dr7; |
| 87 |
| 88 // The contents of context_.float_save effectively alias everything in |
| 89 // context_.fxsave that’s related to x87 FPU state. context_.float_save |
| 90 // doesn’t carry state specific to SSE (or later), such as mxcsr and the xmm |
| 91 // registers. |
| 92 context_.float_save.control_word = context_snapshot->fxsave.fcw; |
| 93 context_.float_save.status_word = context_snapshot->fxsave.fsw; |
| 94 context_.float_save.tag_word = |
| 95 CPUContextX86::FxsaveToFsaveTagWord(context_snapshot->fxsave.fsw, |
| 96 context_snapshot->fxsave.ftw, |
| 97 context_snapshot->fxsave.st_mm); |
| 98 context_.float_save.error_offset = context_snapshot->fxsave.fpu_ip; |
| 99 context_.float_save.error_selector = context_snapshot->fxsave.fpu_cs; |
| 100 context_.float_save.data_offset = context_snapshot->fxsave.fpu_dp; |
| 101 context_.float_save.data_selector = context_snapshot->fxsave.fpu_ds; |
| 102 |
| 103 for (size_t index = 0, offset = 0; |
| 104 index < arraysize(context_snapshot->fxsave.st_mm); |
| 105 offset += sizeof(context_snapshot->fxsave.st_mm[index].st), ++index) { |
| 106 memcpy(&context_.float_save.register_area[offset], |
| 107 &context_snapshot->fxsave.st_mm[index].st, |
| 108 sizeof(context_snapshot->fxsave.st_mm[index].st)); |
| 109 } |
| 110 |
| 111 context_.gs = context_snapshot->gs; |
| 112 context_.fs = context_snapshot->fs; |
| 113 context_.es = context_snapshot->es; |
| 114 context_.ds = context_snapshot->ds; |
| 115 context_.edi = context_snapshot->edi; |
| 116 context_.esi = context_snapshot->esi; |
| 117 context_.ebx = context_snapshot->ebx; |
| 118 context_.edx = context_snapshot->edx; |
| 119 context_.ecx = context_snapshot->ecx; |
| 120 context_.eax = context_snapshot->eax; |
| 121 context_.ebp = context_snapshot->ebp; |
| 122 context_.eip = context_snapshot->eip; |
| 123 context_.cs = context_snapshot->cs; |
| 124 context_.eflags = context_snapshot->eflags; |
| 125 context_.esp = context_snapshot->esp; |
| 126 context_.ss = context_snapshot->ss; |
| 127 |
| 128 // This is effectively a memcpy() of a big structure. |
| 129 context_.fxsave = context_snapshot->fxsave; |
| 130 } |
| 131 |
39 bool MinidumpContextX86Writer::WriteObject(FileWriterInterface* file_writer) { | 132 bool MinidumpContextX86Writer::WriteObject(FileWriterInterface* file_writer) { |
40 DCHECK_EQ(state(), kStateWritable); | 133 DCHECK_EQ(state(), kStateWritable); |
41 | 134 |
42 return file_writer->Write(&context_, sizeof(context_)); | 135 return file_writer->Write(&context_, sizeof(context_)); |
43 } | 136 } |
44 | 137 |
45 size_t MinidumpContextX86Writer::ContextSize() const { | 138 size_t MinidumpContextX86Writer::ContextSize() const { |
46 DCHECK_GE(state(), kStateFrozen); | 139 DCHECK_GE(state(), kStateFrozen); |
47 | 140 |
48 return sizeof(context_); | 141 return sizeof(context_); |
49 } | 142 } |
50 | 143 |
51 MinidumpContextAMD64Writer::MinidumpContextAMD64Writer() | 144 MinidumpContextAMD64Writer::MinidumpContextAMD64Writer() |
52 : MinidumpContextWriter(), context_() { | 145 : MinidumpContextWriter(), context_() { |
53 context_.context_flags = kMinidumpContextAMD64; | 146 context_.context_flags = kMinidumpContextAMD64; |
54 } | 147 } |
55 | 148 |
56 MinidumpContextAMD64Writer::~MinidumpContextAMD64Writer() { | 149 MinidumpContextAMD64Writer::~MinidumpContextAMD64Writer() { |
57 } | 150 } |
58 | 151 |
| 152 void MinidumpContextAMD64Writer::InitializeFromSnapshot( |
| 153 const CPUContextX86_64* context_snapshot) { |
| 154 DCHECK_EQ(state(), kStateMutable); |
| 155 DCHECK_EQ(context_.context_flags, kMinidumpContextAMD64); |
| 156 |
| 157 context_.context_flags = kMinidumpContextAMD64All; |
| 158 |
| 159 context_.mx_csr = context_snapshot->fxsave.mxcsr; |
| 160 context_.cs = context_snapshot->cs; |
| 161 context_.fs = context_snapshot->fs; |
| 162 context_.gs = context_snapshot->gs; |
| 163 context_.eflags = context_snapshot->rflags; |
| 164 context_.dr0 = context_snapshot->dr0; |
| 165 context_.dr1 = context_snapshot->dr1; |
| 166 context_.dr2 = context_snapshot->dr2; |
| 167 context_.dr3 = context_snapshot->dr3; |
| 168 context_.dr6 = context_snapshot->dr6; |
| 169 context_.dr7 = context_snapshot->dr7; |
| 170 context_.rax = context_snapshot->rax; |
| 171 context_.rcx = context_snapshot->rcx; |
| 172 context_.rdx = context_snapshot->rdx; |
| 173 context_.rbx = context_snapshot->rbx; |
| 174 context_.rsp = context_snapshot->rsp; |
| 175 context_.rbp = context_snapshot->rbp; |
| 176 context_.rsi = context_snapshot->rsi; |
| 177 context_.rdi = context_snapshot->rdi; |
| 178 context_.r8 = context_snapshot->r8; |
| 179 context_.r9 = context_snapshot->r9; |
| 180 context_.r10 = context_snapshot->r10; |
| 181 context_.r11 = context_snapshot->r11; |
| 182 context_.r12 = context_snapshot->r12; |
| 183 context_.r13 = context_snapshot->r13; |
| 184 context_.r14 = context_snapshot->r14; |
| 185 context_.r15 = context_snapshot->r15; |
| 186 context_.rip = context_snapshot->rip; |
| 187 |
| 188 // This is effectively a memcpy() of a big structure. |
| 189 context_.fxsave = context_snapshot->fxsave; |
| 190 } |
| 191 |
59 size_t MinidumpContextAMD64Writer::Alignment() { | 192 size_t MinidumpContextAMD64Writer::Alignment() { |
60 DCHECK_GE(state(), kStateFrozen); | 193 DCHECK_GE(state(), kStateFrozen); |
61 | 194 |
62 // Match the alignment of MinidumpContextAMD64. | 195 // Match the alignment of MinidumpContextAMD64. |
63 return 16; | 196 return 16; |
64 } | 197 } |
65 | 198 |
66 bool MinidumpContextAMD64Writer::WriteObject(FileWriterInterface* file_writer) { | 199 bool MinidumpContextAMD64Writer::WriteObject(FileWriterInterface* file_writer) { |
67 DCHECK_EQ(state(), kStateWritable); | 200 DCHECK_EQ(state(), kStateWritable); |
68 | 201 |
69 return file_writer->Write(&context_, sizeof(context_)); | 202 return file_writer->Write(&context_, sizeof(context_)); |
70 } | 203 } |
71 | 204 |
72 size_t MinidumpContextAMD64Writer::ContextSize() const { | 205 size_t MinidumpContextAMD64Writer::ContextSize() const { |
73 DCHECK_GE(state(), kStateFrozen); | 206 DCHECK_GE(state(), kStateFrozen); |
74 | 207 |
75 return sizeof(context_); | 208 return sizeof(context_); |
76 } | 209 } |
77 | 210 |
78 } // namespace crashpad | 211 } // namespace crashpad |
OLD | NEW |