]>
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> | |
17 | ||
18 | typedef struct { | |
19 | int flavor; | |
20 | mach_msg_type_number_t count; | |
21 | } threadflavor_t; | |
22 | ||
23 | static threadflavor_t thread_flavor[] = { | |
24 | #if defined(__i386__) || defined(__x86_64__) | |
25 | { x86_THREAD_STATE, x86_THREAD_STATE_COUNT }, | |
26 | { x86_FLOAT_STATE, x86_FLOAT_STATE_COUNT }, | |
27 | { x86_EXCEPTION_STATE, x86_EXCEPTION_STATE_COUNT }, | |
28 | #elif defined(__arm__) | |
29 | { ARM_THREAD_STATE, ARM_THREAD_STATE_COUNT }, | |
30 | { ARM_VFP_STATE, ARM_VFP_STATE_COUNT }, | |
31 | { ARM_EXCEPTION_STATE, ARM_EXCEPTION_STATE_COUNT }, | |
32 | #elif defined(__arm64__) | |
33 | { ARM_THREAD_STATE64, ARM_THREAD_STATE64_COUNT }, | |
34 | /* ARM64_TODO: NEON? */ | |
35 | { ARM_EXCEPTION_STATE64, ARM_EXCEPTION_STATE64_COUNT }, | |
36 | #else | |
37 | #error architecture not supported | |
38 | #endif | |
39 | }; | |
40 | ||
41 | static const int nthread_flavors = sizeof (thread_flavor) / sizeof (thread_flavor[0]); | |
42 | ||
43 | size_t | |
44 | sizeof_LC_THREAD() | |
45 | { | |
46 | size_t cmdsize = sizeof (struct thread_command); | |
47 | for (int i = 0; i < nthread_flavors; i++) { | |
48 | cmdsize += sizeof (thread_flavor[i]) + | |
49 | thread_flavor[i].count * sizeof (int); | |
50 | } | |
51 | return cmdsize; | |
52 | } | |
53 | ||
54 | void | |
55 | dump_thread_state(native_mach_header_t *mh, struct thread_command *tc, mach_port_t thread) | |
56 | { | |
57 | tc->cmd = LC_THREAD; | |
58 | tc->cmdsize = (uint32_t) sizeof_LC_THREAD(); | |
59 | ||
60 | uint32_t *wbuf = (void *)(tc + 1); | |
61 | ||
62 | for (int f = 0; f < nthread_flavors; f++) { | |
63 | ||
64 | memcpy(wbuf, &thread_flavor[f], sizeof (thread_flavor[f])); | |
65 | wbuf += sizeof (thread_flavor[f]) / sizeof (*wbuf); | |
66 | ||
67 | const kern_return_t kr = thread_get_state(thread, thread_flavor[f].flavor, (thread_state_t)wbuf, &thread_flavor[f].count); | |
68 | if (KERN_SUCCESS != kr) { | |
69 | err_mach(kr, NULL, "getting flavor %d of thread", | |
70 | thread_flavor[f].flavor); | |
71 | bzero(wbuf, thread_flavor[f].count * sizeof (int)); | |
72 | } | |
73 | ||
74 | wbuf += thread_flavor[f].count; | |
75 | } | |
76 | mach_header_inc_ncmds(mh, 1); | |
77 | mach_header_inc_sizeofcmds(mh, tc->cmdsize); | |
78 | } |