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