Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(312)

Side by Side Diff: snapshot/cpu_context_mac.cc

Issue 666483002: Create snapshot/mac and move some files from snapshot and util to there (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad/+/master
Patch Set: Move process_reader, process_types, and mach_o_image*_reader from util/mac to snapshot/mac Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « snapshot/cpu_context_mac.h ('k') | snapshot/cpu_context_mac_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "snapshot/cpu_context_mac.h"
16
17 #include <string.h>
18
19 #include "base/logging.h"
20
21 namespace crashpad {
22
23 #if defined(ARCH_CPU_X86_FAMILY)
24
25 namespace {
26
27 void InitializeCPUContextX86Thread(
28 CPUContextX86* context,
29 const x86_thread_state32_t* x86_thread_state32) {
30 context->eax = x86_thread_state32->__eax;
31 context->ebx = x86_thread_state32->__ebx;
32 context->ecx = x86_thread_state32->__ecx;
33 context->edx = x86_thread_state32->__edx;
34 context->edi = x86_thread_state32->__edi;
35 context->esi = x86_thread_state32->__esi;
36 context->ebp = x86_thread_state32->__ebp;
37 context->esp = x86_thread_state32->__esp;
38 context->eip = x86_thread_state32->__eip;
39 context->eflags = x86_thread_state32->__eflags;
40 context->cs = x86_thread_state32->__cs;
41 context->ds = x86_thread_state32->__ds;
42 context->es = x86_thread_state32->__es;
43 context->fs = x86_thread_state32->__fs;
44 context->gs = x86_thread_state32->__gs;
45 context->ss = x86_thread_state32->__ss;
46 }
47
48 void InitializeCPUContextX86Float(
49 CPUContextX86* context, const x86_float_state32_t* x86_float_state32) {
50 // This relies on both x86_float_state32_t and context->fxsave having
51 // identical (fxsave) layout.
52 static_assert(offsetof(x86_float_state32_t, __fpu_reserved1) -
53 offsetof(x86_float_state32_t, __fpu_fcw) ==
54 sizeof(context->fxsave),
55 "types must be equivalent");
56
57 memcpy(
58 &context->fxsave, &x86_float_state32->__fpu_fcw, sizeof(context->fxsave));
59 }
60
61 void InitializeCPUContextX86Debug(
62 CPUContextX86* context, const x86_debug_state32_t* x86_debug_state32) {
63 context->dr0 = x86_debug_state32->__dr0;
64 context->dr1 = x86_debug_state32->__dr1;
65 context->dr2 = x86_debug_state32->__dr2;
66 context->dr3 = x86_debug_state32->__dr3;
67 context->dr4 = x86_debug_state32->__dr4;
68 context->dr5 = x86_debug_state32->__dr5;
69 context->dr6 = x86_debug_state32->__dr6;
70 context->dr7 = x86_debug_state32->__dr7;
71 }
72
73 // Initializes |context| from the native thread state structure |state|, which
74 // is interpreted according to |flavor|. |state_count| must be at least the
75 // expected size for |flavor|. This handles the architecture-specific
76 // x86_THREAD_STATE32, x86_FLOAT_STATE32, and x86_DEBUG_STATE32 flavors. It also
77 // handles the universal x86_THREAD_STATE, x86_FLOAT_STATE, and x86_DEBUG_STATE
78 // flavors provided that the associated structure carries 32-bit data of the
79 // corresponding state type. |flavor| may be THREAD_STATE_NONE to avoid setting
80 // any thread state in |context|. This returns the architecture-specific flavor
81 // value for the thread state that was actually set, or THREAD_STATE_NONE if no
82 // thread state was set.
83 thread_state_flavor_t InitializeCPUContextX86Flavor(
84 CPUContextX86* context,
85 thread_state_flavor_t flavor,
86 const natural_t* state,
87 mach_msg_type_number_t state_count) {
88 mach_msg_type_number_t expected_state_count;
89 switch (flavor) {
90 case x86_THREAD_STATE:
91 expected_state_count = x86_THREAD_STATE_COUNT;
92 break;
93 case x86_FLOAT_STATE:
94 expected_state_count = x86_FLOAT_STATE_COUNT;
95 break;
96 case x86_DEBUG_STATE:
97 expected_state_count = x86_DEBUG_STATE_COUNT;
98 break;
99 case x86_THREAD_STATE32:
100 expected_state_count = x86_THREAD_STATE32_COUNT;
101 break;
102 case x86_FLOAT_STATE32:
103 expected_state_count = x86_FLOAT_STATE32_COUNT;
104 break;
105 case x86_DEBUG_STATE32:
106 expected_state_count = x86_DEBUG_STATE32_COUNT;
107 break;
108 case THREAD_STATE_NONE:
109 expected_state_count = 0;
110 break;
111 default:
112 LOG(WARNING) << "unhandled flavor " << flavor;
113 return THREAD_STATE_NONE;
114 }
115
116 if (state_count < expected_state_count) {
117 LOG(WARNING) << "expected state_count " << expected_state_count
118 << " for flavor " << flavor << ", observed " << state_count;
119 return THREAD_STATE_NONE;
120 }
121
122 switch (flavor) {
123 case x86_THREAD_STATE: {
124 const x86_thread_state_t* x86_thread_state =
125 reinterpret_cast<const x86_thread_state_t*>(state);
126 if (x86_thread_state->tsh.flavor != x86_THREAD_STATE32) {
127 LOG(WARNING) << "expected flavor x86_THREAD_STATE32, observed "
128 << x86_thread_state->tsh.flavor;
129 return THREAD_STATE_NONE;
130 }
131 return InitializeCPUContextX86Flavor(
132 context,
133 x86_thread_state->tsh.flavor,
134 reinterpret_cast<const natural_t*>(&x86_thread_state->uts.ts32),
135 x86_thread_state->tsh.count);
136 }
137
138 case x86_FLOAT_STATE: {
139 const x86_float_state_t* x86_float_state =
140 reinterpret_cast<const x86_float_state_t*>(state);
141 if (x86_float_state->fsh.flavor != x86_FLOAT_STATE32) {
142 LOG(WARNING) << "expected flavor x86_FLOAT_STATE32, observed "
143 << x86_float_state->fsh.flavor;
144 return THREAD_STATE_NONE;
145 }
146 return InitializeCPUContextX86Flavor(
147 context,
148 x86_float_state->fsh.flavor,
149 reinterpret_cast<const natural_t*>(&x86_float_state->ufs.fs32),
150 x86_float_state->fsh.count);
151 }
152
153 case x86_DEBUG_STATE: {
154 const x86_debug_state_t* x86_debug_state =
155 reinterpret_cast<const x86_debug_state_t*>(state);
156 if (x86_debug_state->dsh.flavor != x86_DEBUG_STATE32) {
157 LOG(WARNING) << "expected flavor x86_DEBUG_STATE32, observed "
158 << x86_debug_state->dsh.flavor;
159 return THREAD_STATE_NONE;
160 }
161 return InitializeCPUContextX86Flavor(
162 context,
163 x86_debug_state->dsh.flavor,
164 reinterpret_cast<const natural_t*>(&x86_debug_state->uds.ds32),
165 x86_debug_state->dsh.count);
166 }
167
168 case x86_THREAD_STATE32: {
169 const x86_thread_state32_t* x86_thread_state32 =
170 reinterpret_cast<const x86_thread_state32_t*>(state);
171 InitializeCPUContextX86Thread(context, x86_thread_state32);
172 return flavor;
173 }
174
175 case x86_FLOAT_STATE32: {
176 const x86_float_state32_t* x86_float_state32 =
177 reinterpret_cast<const x86_float_state32_t*>(state);
178 InitializeCPUContextX86Float(context, x86_float_state32);
179 return flavor;
180 }
181
182 case x86_DEBUG_STATE32: {
183 const x86_debug_state32_t* x86_debug_state32 =
184 reinterpret_cast<const x86_debug_state32_t*>(state);
185 InitializeCPUContextX86Debug(context, x86_debug_state32);
186 return flavor;
187 }
188
189 case THREAD_STATE_NONE: {
190 // This may happen without error when called without exception-style
191 // flavor data, or even from an exception handler when the exception
192 // behavior is EXCEPTION_DEFAULT.
193 return flavor;
194 }
195
196 default: {
197 NOTREACHED();
198 return THREAD_STATE_NONE;
199 }
200 }
201 }
202
203 void InitializeCPUContextX86_64Thread(
204 CPUContextX86_64* context, const x86_thread_state64_t* x86_thread_state64) {
205 context->rax = x86_thread_state64->__rax;
206 context->rbx = x86_thread_state64->__rbx;
207 context->rcx = x86_thread_state64->__rcx;
208 context->rdx = x86_thread_state64->__rdx;
209 context->rdi = x86_thread_state64->__rdi;
210 context->rsi = x86_thread_state64->__rsi;
211 context->rbp = x86_thread_state64->__rbp;
212 context->rsp = x86_thread_state64->__rsp;
213 context->r8 = x86_thread_state64->__r8;
214 context->r9 = x86_thread_state64->__r9;
215 context->r10 = x86_thread_state64->__r10;
216 context->r11 = x86_thread_state64->__r11;
217 context->r12 = x86_thread_state64->__r12;
218 context->r13 = x86_thread_state64->__r13;
219 context->r14 = x86_thread_state64->__r14;
220 context->r15 = x86_thread_state64->__r15;
221 context->rip = x86_thread_state64->__rip;
222 context->rflags = x86_thread_state64->__rflags;
223 context->cs = x86_thread_state64->__cs;
224 context->fs = x86_thread_state64->__fs;
225 context->gs = x86_thread_state64->__gs;
226 }
227
228 void InitializeCPUContextX86_64Float(
229 CPUContextX86_64* context, const x86_float_state64_t* x86_float_state64) {
230 // This relies on both x86_float_state64_t and context->fxsave having
231 // identical (fxsave) layout.
232 static_assert(offsetof(x86_float_state64_t, __fpu_reserved1) -
233 offsetof(x86_float_state64_t, __fpu_fcw) ==
234 sizeof(context->fxsave),
235 "types must be equivalent");
236
237 memcpy(&context->fxsave,
238 &x86_float_state64->__fpu_fcw,
239 sizeof(context->fxsave));
240 }
241
242 void InitializeCPUContextX86_64Debug(
243 CPUContextX86_64* context, const x86_debug_state64_t* x86_debug_state64) {
244 context->dr0 = x86_debug_state64->__dr0;
245 context->dr1 = x86_debug_state64->__dr1;
246 context->dr2 = x86_debug_state64->__dr2;
247 context->dr3 = x86_debug_state64->__dr3;
248 context->dr4 = x86_debug_state64->__dr4;
249 context->dr5 = x86_debug_state64->__dr5;
250 context->dr6 = x86_debug_state64->__dr6;
251 context->dr7 = x86_debug_state64->__dr7;
252 }
253
254 // Initializes |context| from the native thread state structure |state|, which
255 // is interpreted according to |flavor|. |state_count| must be at least the
256 // expected size for |flavor|. This handles the architecture-specific
257 // x86_THREAD_STATE64, x86_FLOAT_STATE64, and x86_DEBUG_STATE64 flavors. It also
258 // handles the universal x86_THREAD_STATE, x86_FLOAT_STATE, and x86_DEBUG_STATE
259 // flavors provided that the associated structure carries 64-bit data of the
260 // corresponding state type. |flavor| may be THREAD_STATE_NONE to avoid setting
261 // any thread state in |context|. This returns the architecture-specific flavor
262 // value for the thread state that was actually set, or THREAD_STATE_NONE if no
263 // thread state was set.
264 thread_state_flavor_t InitializeCPUContextX86_64Flavor(
265 CPUContextX86_64* context,
266 thread_state_flavor_t flavor,
267 const natural_t* state,
268 mach_msg_type_number_t state_count) {
269 mach_msg_type_number_t expected_state_count;
270 switch (flavor) {
271 case x86_THREAD_STATE:
272 expected_state_count = x86_THREAD_STATE_COUNT;
273 break;
274 case x86_FLOAT_STATE:
275 expected_state_count = x86_FLOAT_STATE_COUNT;
276 break;
277 case x86_DEBUG_STATE:
278 expected_state_count = x86_DEBUG_STATE_COUNT;
279 break;
280 case x86_THREAD_STATE64:
281 expected_state_count = x86_THREAD_STATE64_COUNT;
282 break;
283 case x86_FLOAT_STATE64:
284 expected_state_count = x86_FLOAT_STATE64_COUNT;
285 break;
286 case x86_DEBUG_STATE64:
287 expected_state_count = x86_DEBUG_STATE64_COUNT;
288 break;
289 case THREAD_STATE_NONE:
290 expected_state_count = 0;
291 break;
292 default:
293 LOG(WARNING) << "unhandled flavor " << flavor;
294 return THREAD_STATE_NONE;
295 }
296
297 if (state_count < expected_state_count) {
298 LOG(WARNING) << "expected state_count " << expected_state_count
299 << " for flavor " << flavor << ", observed " << state_count;
300 return THREAD_STATE_NONE;
301 }
302
303 switch (flavor) {
304 case x86_THREAD_STATE: {
305 const x86_thread_state_t* x86_thread_state =
306 reinterpret_cast<const x86_thread_state_t*>(state);
307 if (x86_thread_state->tsh.flavor != x86_THREAD_STATE64) {
308 LOG(WARNING) << "expected flavor x86_THREAD_STATE64, observed "
309 << x86_thread_state->tsh.flavor;
310 return THREAD_STATE_NONE;
311 }
312 return InitializeCPUContextX86_64Flavor(
313 context,
314 x86_thread_state->tsh.flavor,
315 reinterpret_cast<const natural_t*>(&x86_thread_state->uts.ts64),
316 x86_thread_state->tsh.count);
317 }
318
319 case x86_FLOAT_STATE: {
320 const x86_float_state_t* x86_float_state =
321 reinterpret_cast<const x86_float_state_t*>(state);
322 if (x86_float_state->fsh.flavor != x86_FLOAT_STATE64) {
323 LOG(WARNING) << "expected flavor x86_FLOAT_STATE64, observed "
324 << x86_float_state->fsh.flavor;
325 return THREAD_STATE_NONE;
326 }
327 return InitializeCPUContextX86_64Flavor(
328 context,
329 x86_float_state->fsh.flavor,
330 reinterpret_cast<const natural_t*>(&x86_float_state->ufs.fs64),
331 x86_float_state->fsh.count);
332 }
333
334 case x86_DEBUG_STATE: {
335 const x86_debug_state_t* x86_debug_state =
336 reinterpret_cast<const x86_debug_state_t*>(state);
337 if (x86_debug_state->dsh.flavor != x86_DEBUG_STATE64) {
338 LOG(WARNING) << "expected flavor x86_DEBUG_STATE64, observed "
339 << x86_debug_state->dsh.flavor;
340 return THREAD_STATE_NONE;
341 }
342 return InitializeCPUContextX86_64Flavor(
343 context,
344 x86_debug_state->dsh.flavor,
345 reinterpret_cast<const natural_t*>(&x86_debug_state->uds.ds64),
346 x86_debug_state->dsh.count);
347 }
348
349 case x86_THREAD_STATE64: {
350 const x86_thread_state64_t* x86_thread_state64 =
351 reinterpret_cast<const x86_thread_state64_t*>(state);
352 InitializeCPUContextX86_64Thread(context, x86_thread_state64);
353 return flavor;
354 }
355
356 case x86_FLOAT_STATE64: {
357 const x86_float_state64_t* x86_float_state64 =
358 reinterpret_cast<const x86_float_state64_t*>(state);
359 InitializeCPUContextX86_64Float(context, x86_float_state64);
360 return flavor;
361 }
362
363 case x86_DEBUG_STATE64: {
364 const x86_debug_state64_t* x86_debug_state64 =
365 reinterpret_cast<const x86_debug_state64_t*>(state);
366 InitializeCPUContextX86_64Debug(context, x86_debug_state64);
367 return flavor;
368 }
369
370 case THREAD_STATE_NONE: {
371 // This may happen without error when called without exception-style
372 // flavor data, or even from an exception handler when the exception
373 // behavior is EXCEPTION_DEFAULT.
374 return flavor;
375 }
376
377 default: {
378 NOTREACHED();
379 return THREAD_STATE_NONE;
380 }
381 }
382 }
383
384 } // namespace
385
386 namespace internal {
387
388 void InitializeCPUContextX86(CPUContextX86* context,
389 thread_state_flavor_t flavor,
390 const natural_t* state,
391 mach_msg_type_number_t state_count,
392 const x86_thread_state32_t* x86_thread_state32,
393 const x86_float_state32_t* x86_float_state32,
394 const x86_debug_state32_t* x86_debug_state32) {
395 thread_state_flavor_t set_flavor = THREAD_STATE_NONE;
396 if (flavor != THREAD_STATE_NONE) {
397 set_flavor =
398 InitializeCPUContextX86Flavor(context, flavor, state, state_count);
399 }
400
401 if (set_flavor != x86_THREAD_STATE32) {
402 InitializeCPUContextX86Thread(context, x86_thread_state32);
403 }
404 if (set_flavor != x86_FLOAT_STATE32) {
405 InitializeCPUContextX86Float(context, x86_float_state32);
406 }
407 if (set_flavor != x86_DEBUG_STATE32) {
408 InitializeCPUContextX86Debug(context, x86_debug_state32);
409 }
410 }
411
412 void InitializeCPUContextX86_64(CPUContextX86_64* context,
413 thread_state_flavor_t flavor,
414 const natural_t* state,
415 mach_msg_type_number_t state_count,
416 const x86_thread_state64_t* x86_thread_state64,
417 const x86_float_state64_t* x86_float_state64,
418 const x86_debug_state64_t* x86_debug_state64) {
419 thread_state_flavor_t set_flavor = THREAD_STATE_NONE;
420 if (flavor != THREAD_STATE_NONE) {
421 set_flavor =
422 InitializeCPUContextX86_64Flavor(context, flavor, state, state_count);
423 }
424
425 if (set_flavor != x86_THREAD_STATE64) {
426 InitializeCPUContextX86_64Thread(context, x86_thread_state64);
427 }
428 if (set_flavor != x86_FLOAT_STATE64) {
429 InitializeCPUContextX86_64Float(context, x86_float_state64);
430 }
431 if (set_flavor != x86_DEBUG_STATE64) {
432 InitializeCPUContextX86_64Debug(context, x86_debug_state64);
433 }
434 }
435
436 } // namespace internal
437
438 #endif
439
440 } // namespace crashpad
OLDNEW
« no previous file with comments | « snapshot/cpu_context_mac.h ('k') | snapshot/cpu_context_mac_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698