-#elif __arm__
- uint32_t i= 0;
- uint32_t frameb[2];
- uint32_t fp= 0;
-
- // get the current frame pointer for this thread
- __asm__ volatile("mov %0,r7" : "=r" (fp));
-
- // now crawl up the stack recording the link value of each frame
- do {
- // check bounds
- if ((fp == 0) || ((fp & 3) != 0) || (fp > VM_MAX_KERNEL_ADDRESS) || (fp < VM_MIN_KERNEL_ADDRESS)) {
- break;
- }
- // safely read frame
- if (copyinframe(fp, frameb) != 0) {
- 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;
+#elif __x86_64__
+#define SANE_x86_64_FRAME_SIZE (kernel_stack_size >> 1)
+ vm_offset_t stackptr, stackptr_prev, raddr;
+ unsigned frame_index = 0;
+/* Obtain current frame pointer */
+
+ __asm__ volatile("movq %%rbp, %0" : "=m" (stackptr));
+
+ if (!x86_64_validate_stackptr(stackptr))
+ goto pad;
+
+ raddr = *((vm_offset_t *) (stackptr + x86_64_RETURN_OFFSET));
+
+ if (!x86_64_validate_raddr(raddr))
+ goto pad;
+
+ bt[frame_index++] = (void *) raddr;
+
+ for ( ; frame_index < maxAddrs; frame_index++) {
+ stackptr_prev = stackptr;
+ stackptr = *((vm_offset_t *) stackptr_prev);
+
+ if (!x86_64_validate_stackptr(stackptr))
+ break;
+ /* Stack grows downwards */
+ if (stackptr < stackptr_prev)
+ break;
+
+ if ((stackptr - stackptr_prev) > SANE_x86_64_FRAME_SIZE)
+ break;
+
+ raddr = *((vm_offset_t *) (stackptr + x86_64_RETURN_OFFSET));
+
+ if (!x86_64_validate_raddr(raddr))
+ break;
+
+ bt[frame_index] = (void *) raddr;
+ }
+pad:
+ frame = frame_index;
+
+ for ( ; frame_index < maxAddrs; frame_index++)
+ bt[frame_index] = (void *) 0;