]> git.saurik.com Git - apple/system_cmds.git/blob - gcore.tproj/threads.c
9903803ef78729dd52a9de6318a76dbe1569ccf4
[apple/system_cmds.git] / gcore.tproj / threads.c
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 }