]>
Commit | Line | Data |
---|---|---|
cf37c299 A |
1 | /* |
2 | * Copyright (c) 2015 Apple Inc. All rights reserved. | |
3 | */ | |
4 | ||
5 | #include "options.h" | |
6 | #include "utils.h" | |
7 | #include "threads.h" | |
8 | #include "corefile.h" | |
9 | ||
10 | #include <sys/types.h> | |
11 | #include <mach/mach.h> | |
12 | #include <mach/task.h> | |
13 | #include <stdio.h> | |
14 | #include <stdlib.h> | |
15 | #include <unistd.h> | |
16 | #include <errno.h> | |
887d5eed | 17 | #include <stddef.h> |
cf37c299 A |
18 | |
19 | typedef struct { | |
20 | int flavor; | |
21 | mach_msg_type_number_t count; | |
22 | } threadflavor_t; | |
23 | ||
24 | static threadflavor_t thread_flavor[] = { | |
25 | #if defined(__i386__) || defined(__x86_64__) | |
26 | { x86_THREAD_STATE, x86_THREAD_STATE_COUNT }, | |
27 | { x86_FLOAT_STATE, x86_FLOAT_STATE_COUNT }, | |
28 | { x86_EXCEPTION_STATE, x86_EXCEPTION_STATE_COUNT }, | |
29 | #elif defined(__arm__) | |
30 | { ARM_THREAD_STATE, ARM_THREAD_STATE_COUNT }, | |
31 | { ARM_VFP_STATE, ARM_VFP_STATE_COUNT }, | |
32 | { ARM_EXCEPTION_STATE, ARM_EXCEPTION_STATE_COUNT }, | |
33 | #elif defined(__arm64__) | |
34 | { ARM_THREAD_STATE64, ARM_THREAD_STATE64_COUNT }, | |
35 | /* ARM64_TODO: NEON? */ | |
36 | { ARM_EXCEPTION_STATE64, ARM_EXCEPTION_STATE64_COUNT }, | |
37 | #else | |
38 | #error architecture not supported | |
39 | #endif | |
40 | }; | |
41 | ||
42 | static const int nthread_flavors = sizeof (thread_flavor) / sizeof (thread_flavor[0]); | |
43 | ||
44 | size_t | |
45 | sizeof_LC_THREAD() | |
46 | { | |
47 | size_t cmdsize = sizeof (struct thread_command); | |
48 | for (int i = 0; i < nthread_flavors; i++) { | |
49 | cmdsize += sizeof (thread_flavor[i]) + | |
50 | thread_flavor[i].count * sizeof (int); | |
51 | } | |
52 | return cmdsize; | |
53 | } | |
54 | ||
55 | void | |
56 | dump_thread_state(native_mach_header_t *mh, struct thread_command *tc, mach_port_t thread) | |
57 | { | |
58 | tc->cmd = LC_THREAD; | |
59 | tc->cmdsize = (uint32_t) sizeof_LC_THREAD(); | |
60 | ||
61 | uint32_t *wbuf = (void *)(tc + 1); | |
62 | ||
63 | for (int f = 0; f < nthread_flavors; f++) { | |
64 | ||
65 | memcpy(wbuf, &thread_flavor[f], sizeof (thread_flavor[f])); | |
66 | wbuf += sizeof (thread_flavor[f]) / sizeof (*wbuf); | |
67 | ||
68 | const kern_return_t kr = thread_get_state(thread, thread_flavor[f].flavor, (thread_state_t)wbuf, &thread_flavor[f].count); | |
69 | if (KERN_SUCCESS != kr) { | |
70 | err_mach(kr, NULL, "getting flavor %d of thread", | |
71 | thread_flavor[f].flavor); | |
72 | bzero(wbuf, thread_flavor[f].count * sizeof (int)); | |
73 | } | |
74 | ||
75 | wbuf += thread_flavor[f].count; | |
76 | } | |
887d5eed A |
77 | assert((ptrdiff_t)tc->cmdsize == ((caddr_t)wbuf - (caddr_t)tc)); |
78 | ||
cf37c299 A |
79 | mach_header_inc_ncmds(mh, 1); |
80 | mach_header_inc_sizeofcmds(mh, tc->cmdsize); | |
81 | } |