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/test/minidump_context_test_util.h" | 15 #include "minidump/test/minidump_context_test_util.h" |
16 | 16 |
17 #include <string.h> | 17 #include <string.h> |
18 #include <sys/types.h> | 18 #include <sys/types.h> |
19 | 19 |
20 #include "base/format_macros.h" | 20 #include "base/format_macros.h" |
21 #include "base/macros.h" | 21 #include "base/macros.h" |
22 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
23 #include "gtest/gtest.h" | 23 #include "gtest/gtest.h" |
24 #include "snapshot/cpu_context.h" | 24 #include "snapshot/cpu_context.h" |
25 #include "snapshot/test/test_cpu_context.h" | 25 #include "snapshot/test/test_cpu_context.h" |
26 #include "test/hex_string.h" | |
27 | 26 |
28 namespace crashpad { | 27 namespace crashpad { |
29 namespace test { | 28 namespace test { |
30 | 29 |
31 void InitializeMinidumpContextX86(MinidumpContextX86* context, uint32_t seed) { | 30 void InitializeMinidumpContextX86(MinidumpContextX86* context, uint32_t seed) { |
32 if (seed == 0) { | 31 if (seed == 0) { |
33 memset(context, 0, sizeof(*context)); | 32 memset(context, 0, sizeof(*context)); |
34 context->context_flags = kMinidumpContextX86; | 33 context->context_flags = kMinidumpContextX86; |
35 return; | 34 return; |
36 } | 35 } |
(...skipping 13 matching lines...) Expand all Loading... |
50 context->eip = value++; | 49 context->eip = value++; |
51 context->eflags = value++; | 50 context->eflags = value++; |
52 context->cs = value++ & 0xffff; | 51 context->cs = value++ & 0xffff; |
53 context->ds = value++ & 0xffff; | 52 context->ds = value++ & 0xffff; |
54 context->es = value++ & 0xffff; | 53 context->es = value++ & 0xffff; |
55 context->fs = value++ & 0xffff; | 54 context->fs = value++ & 0xffff; |
56 context->gs = value++ & 0xffff; | 55 context->gs = value++ & 0xffff; |
57 context->ss = value++ & 0xffff; | 56 context->ss = value++ & 0xffff; |
58 | 57 |
59 InitializeCPUContextX86Fxsave(&context->fxsave, &value); | 58 InitializeCPUContextX86Fxsave(&context->fxsave, &value); |
60 CPUContextX86::FxsaveToFsave(context->fxsave, &context->fsave); | |
61 | 59 |
62 context->dr0 = value++; | 60 context->dr0 = value++; |
63 context->dr1 = value++; | 61 context->dr1 = value++; |
64 context->dr2 = value++; | 62 context->dr2 = value++; |
65 context->dr3 = value++; | 63 context->dr3 = value++; |
66 value += 2; // Minidumps don’t carry dr4 or dr5. | 64 value += 2; // Minidumps don’t carry dr4 or dr5. |
67 context->dr6 = value++; | 65 context->dr6 = value++; |
68 context->dr7 = value++; | 66 context->dr7 = value++; |
69 | 67 |
| 68 // Copy the values that are aliased between the fxsave area |
| 69 // (context->extended_registers) and the floating-point save area |
| 70 // (context->float_save). |
| 71 context->float_save.control_word = context->fxsave.fcw; |
| 72 context->float_save.status_word = context->fxsave.fsw; |
| 73 context->float_save.tag_word = CPUContextX86::FxsaveToFsaveTagWord( |
| 74 context->fxsave.fsw, context->fxsave.ftw, context->fxsave.st_mm); |
| 75 context->float_save.error_offset = context->fxsave.fpu_ip; |
| 76 context->float_save.error_selector = context->fxsave.fpu_cs; |
| 77 context->float_save.data_offset = context->fxsave.fpu_dp; |
| 78 context->float_save.data_selector = context->fxsave.fpu_ds; |
| 79 for (size_t st_mm_index = 0; |
| 80 st_mm_index < arraysize(context->fxsave.st_mm); |
| 81 ++st_mm_index) { |
| 82 for (size_t byte = 0; |
| 83 byte < arraysize(context->fxsave.st_mm[st_mm_index].st); |
| 84 ++byte) { |
| 85 size_t st_index = |
| 86 st_mm_index * arraysize(context->fxsave.st_mm[st_mm_index].st) + byte; |
| 87 context->float_save.register_area[st_index] = |
| 88 context->fxsave.st_mm[st_mm_index].st[byte]; |
| 89 } |
| 90 } |
| 91 |
70 // Set this field last, because it has no analogue in CPUContextX86. | 92 // Set this field last, because it has no analogue in CPUContextX86. |
71 context->float_save.spare_0 = value++; | 93 context->float_save.spare_0 = value++; |
72 } | 94 } |
73 | 95 |
74 void InitializeMinidumpContextAMD64(MinidumpContextAMD64* context, | 96 void InitializeMinidumpContextAMD64(MinidumpContextAMD64* context, |
75 uint32_t seed) { | 97 uint32_t seed) { |
76 if (seed == 0) { | 98 if (seed == 0) { |
77 memset(context, 0, sizeof(*context)); | 99 memset(context, 0, sizeof(*context)); |
78 context->context_flags = kMinidumpContextAMD64; | 100 context->context_flags = kMinidumpContextAMD64; |
79 return; | 101 return; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 EXPECT_EQ(expected->reserved_2, observed->reserved_2); | 181 EXPECT_EQ(expected->reserved_2, observed->reserved_2); |
160 EXPECT_EQ(expected->fpu_dp, observed->fpu_dp); | 182 EXPECT_EQ(expected->fpu_dp, observed->fpu_dp); |
161 EXPECT_EQ(expected->fpu_ds, observed->fpu_ds); | 183 EXPECT_EQ(expected->fpu_ds, observed->fpu_ds); |
162 EXPECT_EQ(expected->reserved_3, observed->reserved_3); | 184 EXPECT_EQ(expected->reserved_3, observed->reserved_3); |
163 EXPECT_EQ(expected->mxcsr, observed->mxcsr); | 185 EXPECT_EQ(expected->mxcsr, observed->mxcsr); |
164 EXPECT_EQ(expected->mxcsr_mask, observed->mxcsr_mask); | 186 EXPECT_EQ(expected->mxcsr_mask, observed->mxcsr_mask); |
165 for (size_t st_mm_index = 0; | 187 for (size_t st_mm_index = 0; |
166 st_mm_index < arraysize(expected->st_mm); | 188 st_mm_index < arraysize(expected->st_mm); |
167 ++st_mm_index) { | 189 ++st_mm_index) { |
168 SCOPED_TRACE(base::StringPrintf("st_mm_index %" PRIuS, st_mm_index)); | 190 SCOPED_TRACE(base::StringPrintf("st_mm_index %" PRIuS, st_mm_index)); |
169 EXPECT_EQ(BytesToHexString(expected->st_mm[st_mm_index].st, | 191 for (size_t byte = 0; |
170 arraysize(expected->st_mm[st_mm_index].st)), | 192 byte < arraysize(expected->st_mm[st_mm_index].st); |
171 BytesToHexString(observed->st_mm[st_mm_index].st, | 193 ++byte) { |
172 arraysize(observed->st_mm[st_mm_index].st))); | 194 EXPECT_EQ(expected->st_mm[st_mm_index].st[byte], |
173 EXPECT_EQ( | 195 observed->st_mm[st_mm_index].st[byte]) << "byte " << byte; |
174 BytesToHexString(expected->st_mm[st_mm_index].st_reserved, | 196 } |
175 arraysize(expected->st_mm[st_mm_index].st_reserved)), | 197 for (size_t byte = 0; |
176 BytesToHexString(observed->st_mm[st_mm_index].st_reserved, | 198 byte < arraysize(expected->st_mm[st_mm_index].st_reserved); |
177 arraysize(observed->st_mm[st_mm_index].st_reserved))); | 199 ++byte) { |
| 200 EXPECT_EQ(expected->st_mm[st_mm_index].st_reserved[byte], |
| 201 observed->st_mm[st_mm_index].st_reserved[byte]) |
| 202 << "byte " << byte; |
| 203 } |
178 } | 204 } |
179 for (size_t xmm_index = 0; | 205 for (size_t xmm_index = 0; |
180 xmm_index < arraysize(expected->xmm); | 206 xmm_index < arraysize(expected->xmm); |
181 ++xmm_index) { | 207 ++xmm_index) { |
182 EXPECT_EQ(BytesToHexString(expected->xmm[xmm_index], | 208 SCOPED_TRACE(base::StringPrintf("xmm_index %" PRIuS, xmm_index)); |
183 arraysize(expected->xmm[xmm_index])), | 209 for (size_t byte = 0; byte < arraysize(expected->xmm[xmm_index]); ++byte) { |
184 BytesToHexString(observed->xmm[xmm_index], | 210 EXPECT_EQ(expected->xmm[xmm_index][byte], observed->xmm[xmm_index][byte]) |
185 arraysize(observed->xmm[xmm_index]))) | 211 << "byte " << byte; |
186 << "xmm_index " << xmm_index; | 212 } |
187 } | 213 } |
188 EXPECT_EQ( | 214 for (size_t byte = 0; byte < arraysize(expected->reserved_4); ++byte) { |
189 BytesToHexString(expected->reserved_4, arraysize(expected->reserved_4)), | 215 EXPECT_EQ(expected->reserved_4[byte], observed->reserved_4[byte]) |
190 BytesToHexString(observed->reserved_4, arraysize(observed->reserved_4))); | 216 << "byte " << byte; |
191 EXPECT_EQ( | 217 } |
192 BytesToHexString(expected->available, arraysize(expected->available)), | 218 for (size_t byte = 0; byte < arraysize(expected->available); ++byte) { |
193 BytesToHexString(observed->available, arraysize(observed->available))); | 219 EXPECT_EQ(expected->available[byte], observed->available[byte]) |
| 220 << "byte " << byte; |
| 221 } |
194 } | 222 } |
195 | 223 |
196 } // namespace | 224 } // namespace |
197 | 225 |
198 void ExpectMinidumpContextX86( | 226 void ExpectMinidumpContextX86( |
199 uint32_t expect_seed, const MinidumpContextX86* observed, bool snapshot) { | 227 uint32_t expect_seed, const MinidumpContextX86* observed, bool snapshot) { |
200 MinidumpContextX86 expected; | 228 MinidumpContextX86 expected; |
201 InitializeMinidumpContextX86(&expected, expect_seed); | 229 InitializeMinidumpContextX86(&expected, expect_seed); |
202 | 230 |
203 EXPECT_EQ(expected.context_flags, observed->context_flags); | 231 EXPECT_EQ(expected.context_flags, observed->context_flags); |
204 EXPECT_EQ(expected.dr0, observed->dr0); | 232 EXPECT_EQ(expected.dr0, observed->dr0); |
205 EXPECT_EQ(expected.dr1, observed->dr1); | 233 EXPECT_EQ(expected.dr1, observed->dr1); |
206 EXPECT_EQ(expected.dr2, observed->dr2); | 234 EXPECT_EQ(expected.dr2, observed->dr2); |
207 EXPECT_EQ(expected.dr3, observed->dr3); | 235 EXPECT_EQ(expected.dr3, observed->dr3); |
208 EXPECT_EQ(expected.dr6, observed->dr6); | 236 EXPECT_EQ(expected.dr6, observed->dr6); |
209 EXPECT_EQ(expected.dr7, observed->dr7); | 237 EXPECT_EQ(expected.dr7, observed->dr7); |
210 | 238 |
211 EXPECT_EQ(expected.fsave.fcw, observed->fsave.fcw); | 239 EXPECT_EQ(expected.float_save.control_word, |
212 EXPECT_EQ(expected.fsave.fsw, observed->fsave.fsw); | 240 observed->float_save.control_word); |
213 EXPECT_EQ(expected.fsave.ftw, observed->fsave.ftw); | 241 EXPECT_EQ(expected.float_save.status_word, observed->float_save.status_word); |
214 EXPECT_EQ(expected.fsave.fpu_ip, observed->fsave.fpu_ip); | 242 EXPECT_EQ(expected.float_save.tag_word, observed->float_save.tag_word); |
215 EXPECT_EQ(expected.fsave.fpu_cs, observed->fsave.fpu_cs); | 243 EXPECT_EQ(expected.float_save.error_offset, |
216 EXPECT_EQ(expected.fsave.fpu_dp, observed->fsave.fpu_dp); | 244 observed->float_save.error_offset); |
217 EXPECT_EQ(expected.fsave.fpu_ds, observed->fsave.fpu_ds); | 245 EXPECT_EQ(expected.float_save.error_selector, |
218 for (size_t index = 0; index < arraysize(expected.fsave.st); ++index) { | 246 observed->float_save.error_selector); |
219 EXPECT_EQ(BytesToHexString(expected.fsave.st[index], | 247 EXPECT_EQ(expected.float_save.data_offset, observed->float_save.data_offset); |
220 arraysize(expected.fsave.st[index])), | 248 EXPECT_EQ(expected.float_save.data_selector, |
221 BytesToHexString(observed->fsave.st[index], | 249 observed->float_save.data_selector); |
222 arraysize(observed->fsave.st[index]))) | 250 for (size_t index = 0; |
223 << "index " << index; | 251 index < arraysize(expected.float_save.register_area); |
| 252 ++index) { |
| 253 EXPECT_EQ(expected.float_save.register_area[index], |
| 254 observed->float_save.register_area[index]) << "index " << index; |
224 } | 255 } |
225 if (snapshot) { | 256 if (snapshot) { |
226 EXPECT_EQ(0u, observed->float_save.spare_0); | 257 EXPECT_EQ(0u, observed->float_save.spare_0); |
227 } else { | 258 } else { |
228 EXPECT_EQ(expected.float_save.spare_0, observed->float_save.spare_0); | 259 EXPECT_EQ(expected.float_save.spare_0, observed->float_save.spare_0); |
229 } | 260 } |
230 | 261 |
231 EXPECT_EQ(expected.gs, observed->gs); | 262 EXPECT_EQ(expected.gs, observed->gs); |
232 EXPECT_EQ(expected.fs, observed->fs); | 263 EXPECT_EQ(expected.fs, observed->fs); |
233 EXPECT_EQ(expected.es, observed->es); | 264 EXPECT_EQ(expected.es, observed->es); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 EXPECT_EQ(expected.last_branch_to_rip, observed->last_branch_to_rip); | 374 EXPECT_EQ(expected.last_branch_to_rip, observed->last_branch_to_rip); |
344 EXPECT_EQ(expected.last_branch_from_rip, observed->last_branch_from_rip); | 375 EXPECT_EQ(expected.last_branch_from_rip, observed->last_branch_from_rip); |
345 EXPECT_EQ(expected.last_exception_to_rip, observed->last_exception_to_rip); | 376 EXPECT_EQ(expected.last_exception_to_rip, observed->last_exception_to_rip); |
346 EXPECT_EQ(expected.last_exception_from_rip, | 377 EXPECT_EQ(expected.last_exception_from_rip, |
347 observed->last_exception_from_rip); | 378 observed->last_exception_from_rip); |
348 } | 379 } |
349 } | 380 } |
350 | 381 |
351 } // namespace test | 382 } // namespace test |
352 } // namespace crashpad | 383 } // namespace crashpad |
OLD | NEW |