summaryrefslogtreecommitdiffstats
path: root/system_cmds/gcore.tproj/threads.c
diff options
context:
space:
mode:
Diffstat (limited to 'system_cmds/gcore.tproj/threads.c')
-rw-r--r--system_cmds/gcore.tproj/threads.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/system_cmds/gcore.tproj/threads.c b/system_cmds/gcore.tproj/threads.c
new file mode 100644
index 0000000..b1b3d6f
--- /dev/null
+++ b/system_cmds/gcore.tproj/threads.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015 Apple Inc. All rights reserved.
+ */
+
+#include "options.h"
+#include "utils.h"
+#include "threads.h"
+#include "corefile.h"
+
+#include <sys/types.h>
+#include <mach/mach.h>
+#include <mach/task.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stddef.h>
+
+typedef struct {
+ int flavor;
+ mach_msg_type_number_t count;
+} threadflavor_t;
+
+static threadflavor_t thread_flavor[] = {
+#if defined(__i386__) || defined(__x86_64__)
+ { x86_THREAD_STATE, x86_THREAD_STATE_COUNT },
+ { x86_FLOAT_STATE, x86_FLOAT_STATE_COUNT },
+ { x86_EXCEPTION_STATE, x86_EXCEPTION_STATE_COUNT },
+#elif defined(__arm__)
+ { ARM_THREAD_STATE, ARM_THREAD_STATE_COUNT },
+ { ARM_VFP_STATE, ARM_VFP_STATE_COUNT },
+ { ARM_EXCEPTION_STATE, ARM_EXCEPTION_STATE_COUNT },
+#elif defined(__arm64__)
+ { ARM_THREAD_STATE64, ARM_THREAD_STATE64_COUNT },
+ /* ARM64_TODO: NEON? */
+ { ARM_EXCEPTION_STATE64, ARM_EXCEPTION_STATE64_COUNT },
+#else
+#error architecture not supported
+#endif
+};
+
+static const int nthread_flavors = sizeof (thread_flavor) / sizeof (thread_flavor[0]);
+
+size_t
+sizeof_LC_THREAD()
+{
+ size_t cmdsize = sizeof (struct thread_command);
+ for (int i = 0; i < nthread_flavors; i++) {
+ cmdsize += sizeof (thread_flavor[i]) +
+ thread_flavor[i].count * sizeof (int);
+ }
+ return cmdsize;
+}
+
+void
+dump_thread_state(native_mach_header_t *mh, struct thread_command *tc, mach_port_t thread)
+{
+ tc->cmd = LC_THREAD;
+ tc->cmdsize = (uint32_t) sizeof_LC_THREAD();
+
+ uint32_t *wbuf = (void *)(tc + 1);
+
+ for (int f = 0; f < nthread_flavors; f++) {
+
+ memcpy(wbuf, &thread_flavor[f], sizeof (thread_flavor[f]));
+ wbuf += sizeof (thread_flavor[f]) / sizeof (*wbuf);
+
+ const kern_return_t kr = thread_get_state(thread, thread_flavor[f].flavor, (thread_state_t)wbuf, &thread_flavor[f].count);
+ if (KERN_SUCCESS != kr) {
+ err_mach(kr, NULL, "getting flavor %d of thread",
+ thread_flavor[f].flavor);
+ bzero(wbuf, thread_flavor[f].count * sizeof (int));
+ }
+
+ wbuf += thread_flavor[f].count;
+ }
+ assert((ptrdiff_t)tc->cmdsize == ((caddr_t)wbuf - (caddr_t)tc));
+
+ mach_header_inc_ncmds(mh, 1);
+ mach_header_inc_sizeofcmds(mh, tc->cmdsize);
+}