Chromium Code Reviews| 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; | |
|
Robert Sesek
2014/11/03 21:26:57
Why |= here? The other operations of this method a
| |
| 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 context_.float_save.control_word = context_snapshot->fxsave.fcw; | |
| 89 context_.float_save.status_word = context_snapshot->fxsave.fsw; | |
| 90 context_.float_save.tag_word = | |
| 91 CPUContextX86::FxsaveToFsaveTagWord(context_snapshot->fxsave.fsw, | |
| 92 context_snapshot->fxsave.ftw, | |
| 93 context_snapshot->fxsave.st_mm); | |
| 94 context_.float_save.error_offset = context_snapshot->fxsave.fpu_ip; | |
| 95 context_.float_save.error_selector = context_snapshot->fxsave.fpu_cs; | |
| 96 context_.float_save.data_offset = context_snapshot->fxsave.fpu_dp; | |
| 97 context_.float_save.data_selector = context_snapshot->fxsave.fpu_ds; | |
| 98 | |
| 99 for (size_t index = 0, offset = 0; | |
| 100 index < arraysize(context_snapshot->fxsave.st_mm); | |
| 101 offset += sizeof(context_snapshot->fxsave.st_mm[index].st), ++index) { | |
| 102 memcpy(&context_.float_save.register_area[offset], | |
| 103 &context_snapshot->fxsave.st_mm[index].st, | |
| 104 sizeof(context_snapshot->fxsave.st_mm[index].st)); | |
| 105 } | |
|
Robert Sesek
2014/11/03 21:26:57
What about fxsave.xmm ?
Mark Mentovai
2014/11/03 22:01:21
Robert Sesek wrote:
| |
| 106 | |
| 107 context_.gs = context_snapshot->gs; | |
| 108 context_.fs = context_snapshot->fs; | |
| 109 context_.es = context_snapshot->es; | |
| 110 context_.ds = context_snapshot->ds; | |
| 111 context_.edi = context_snapshot->edi; | |
| 112 context_.esi = context_snapshot->esi; | |
| 113 context_.ebx = context_snapshot->ebx; | |
| 114 context_.edx = context_snapshot->edx; | |
| 115 context_.ecx = context_snapshot->ecx; | |
| 116 context_.eax = context_snapshot->eax; | |
| 117 context_.ebp = context_snapshot->ebp; | |
| 118 context_.eip = context_snapshot->eip; | |
| 119 context_.cs = context_snapshot->cs; | |
| 120 context_.eflags = context_snapshot->eflags; | |
| 121 context_.esp = context_snapshot->esp; | |
| 122 context_.ss = context_snapshot->ss; | |
| 123 | |
| 124 context_.fxsave = context_snapshot->fxsave; | |
| 125 } | |
| 126 | |
| 39 bool MinidumpContextX86Writer::WriteObject(FileWriterInterface* file_writer) { | 127 bool MinidumpContextX86Writer::WriteObject(FileWriterInterface* file_writer) { |
| 40 DCHECK_EQ(state(), kStateWritable); | 128 DCHECK_EQ(state(), kStateWritable); |
| 41 | 129 |
| 42 return file_writer->Write(&context_, sizeof(context_)); | 130 return file_writer->Write(&context_, sizeof(context_)); |
| 43 } | 131 } |
| 44 | 132 |
| 45 size_t MinidumpContextX86Writer::ContextSize() const { | 133 size_t MinidumpContextX86Writer::ContextSize() const { |
| 46 DCHECK_GE(state(), kStateFrozen); | 134 DCHECK_GE(state(), kStateFrozen); |
| 47 | 135 |
| 48 return sizeof(context_); | 136 return sizeof(context_); |
| 49 } | 137 } |
| 50 | 138 |
| 51 MinidumpContextAMD64Writer::MinidumpContextAMD64Writer() | 139 MinidumpContextAMD64Writer::MinidumpContextAMD64Writer() |
| 52 : MinidumpContextWriter(), context_() { | 140 : MinidumpContextWriter(), context_() { |
| 53 context_.context_flags = kMinidumpContextAMD64; | 141 context_.context_flags = kMinidumpContextAMD64; |
| 54 } | 142 } |
| 55 | 143 |
| 56 MinidumpContextAMD64Writer::~MinidumpContextAMD64Writer() { | 144 MinidumpContextAMD64Writer::~MinidumpContextAMD64Writer() { |
| 57 } | 145 } |
| 58 | 146 |
| 147 void MinidumpContextAMD64Writer::InitializeFromSnapshot( | |
| 148 const CPUContextX86_64* context_snapshot) { | |
| 149 DCHECK_EQ(state(), kStateMutable); | |
| 150 DCHECK_EQ(context_.context_flags, kMinidumpContextAMD64); | |
| 151 | |
| 152 context_.context_flags |= kMinidumpContextAMD64All; | |
|
Robert Sesek
2014/11/03 21:26:57
Same, why |= ?
| |
| 153 | |
| 154 context_.mx_csr = context_snapshot->fxsave.mxcsr; | |
| 155 context_.cs = context_snapshot->cs; | |
|
Robert Sesek
2014/11/03 21:26:57
Why does Context have cs if it's supposed to be ze
Mark Mentovai
2014/11/03 22:01:21
Robert Sesek wrote:
Robert Sesek
2014/11/03 22:22:06
Acknowledged. Thanks for the details.
Mark Mentovai
2014/11/03 22:43:21
I think the AMD doc is a lot clearer on this. AMD
| |
| 156 context_.fs = context_snapshot->fs; | |
| 157 context_.gs = context_snapshot->gs; | |
| 158 context_.eflags = context_snapshot->rflags; | |
| 159 context_.dr0 = context_snapshot->dr0; | |
| 160 context_.dr1 = context_snapshot->dr1; | |
| 161 context_.dr2 = context_snapshot->dr2; | |
| 162 context_.dr3 = context_snapshot->dr3; | |
| 163 context_.dr6 = context_snapshot->dr6; | |
| 164 context_.dr7 = context_snapshot->dr7; | |
| 165 context_.rax = context_snapshot->rax; | |
| 166 context_.rcx = context_snapshot->rcx; | |
| 167 context_.rdx = context_snapshot->rdx; | |
| 168 context_.rbx = context_snapshot->rbx; | |
| 169 context_.rsp = context_snapshot->rsp; | |
| 170 context_.rbp = context_snapshot->rbp; | |
| 171 context_.rsi = context_snapshot->rsi; | |
| 172 context_.rdi = context_snapshot->rdi; | |
| 173 context_.r8 = context_snapshot->r8; | |
| 174 context_.r9 = context_snapshot->r9; | |
| 175 context_.r10 = context_snapshot->r10; | |
| 176 context_.r11 = context_snapshot->r11; | |
| 177 context_.r12 = context_snapshot->r12; | |
| 178 context_.r13 = context_snapshot->r13; | |
| 179 context_.r14 = context_snapshot->r14; | |
| 180 context_.r15 = context_snapshot->r15; | |
| 181 context_.rip = context_snapshot->rip; | |
| 182 | |
| 183 context_.fxsave = context_snapshot->fxsave; | |
| 184 } | |
| 185 | |
| 59 size_t MinidumpContextAMD64Writer::Alignment() { | 186 size_t MinidumpContextAMD64Writer::Alignment() { |
| 60 DCHECK_GE(state(), kStateFrozen); | 187 DCHECK_GE(state(), kStateFrozen); |
| 61 | 188 |
| 62 // Match the alignment of MinidumpContextAMD64. | 189 // Match the alignment of MinidumpContextAMD64. |
| 63 return 16; | 190 return 16; |
| 64 } | 191 } |
| 65 | 192 |
| 66 bool MinidumpContextAMD64Writer::WriteObject(FileWriterInterface* file_writer) { | 193 bool MinidumpContextAMD64Writer::WriteObject(FileWriterInterface* file_writer) { |
| 67 DCHECK_EQ(state(), kStateWritable); | 194 DCHECK_EQ(state(), kStateWritable); |
| 68 | 195 |
| 69 return file_writer->Write(&context_, sizeof(context_)); | 196 return file_writer->Write(&context_, sizeof(context_)); |
| 70 } | 197 } |
| 71 | 198 |
| 72 size_t MinidumpContextAMD64Writer::ContextSize() const { | 199 size_t MinidumpContextAMD64Writer::ContextSize() const { |
| 73 DCHECK_GE(state(), kStateFrozen); | 200 DCHECK_GE(state(), kStateFrozen); |
| 74 | 201 |
| 75 return sizeof(context_); | 202 return sizeof(context_); |
| 76 } | 203 } |
| 77 | 204 |
| 78 } // namespace crashpad | 205 } // namespace crashpad |
| OLD | NEW |