+#elif __arm__ || __arm64__
+ uint32_t i = 0;
+ uintptr_t frameb[2];
+ uintptr_t fp = 0;
+
+ // get the current frame pointer for this thread
+#if defined(__arm__)
+#define OSBacktraceFrameAlignOK(x) (((x) & 0x3) == 0)
+ __asm__ volatile("mov %0,r7" : "=r" (fp));
+#elif defined(__arm64__)
+#define OSBacktraceFrameAlignOK(x) (((x) & 0xf) == 0)
+ __asm__ volatile("mov %0, fp" : "=r" (fp));
+#else
+#error Unknown architecture.
+#endif
+
+ // now crawl up the stack recording the link value of each frame
+ do {
+ // check bounds
+ if ((fp == 0) || (!OSBacktraceFrameAlignOK(fp)) || (fp > VM_MAX_KERNEL_ADDRESS) || (fp < VM_MIN_KERNEL_AND_KEXT_ADDRESS)) {
+ break;
+ }
+ // safely read frame
+#ifdef __arm64__
+ if (copyinframe(fp, (char*)frameb, TRUE) != 0) {
+#else
+ if (copyinframe(fp, (char*)frameb) != 0) {
+#endif
+ break;
+ }
+
+ // No need to use copyin as this is always a kernel address, see check above
+ bt[i] = (void*)frameb[1]; // link register
+ fp = frameb[0];
+ } while (++i < maxAddrs);
+ frame= i;