]> git.cameronkatri.com Git - apple_cmds.git/blob - system_cmds/gcore.tproj/threads.c
Merge branch 'apple'
[apple_cmds.git] / system_cmds / 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 #include <stddef.h>
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 }
77 assert((ptrdiff_t)tc->cmdsize == ((caddr_t)wbuf - (caddr_t)tc));
78
79 mach_header_inc_ncmds(mh, 1);
80 mach_header_inc_sizeofcmds(mh, tc->cmdsize);
81 }