Loading...
libkern/gen/OSDebug.cpp xnu-1228.0.2 xnu-1228
--- xnu/xnu-1228.0.2/libkern/gen/OSDebug.cpp
+++ xnu/xnu-1228/libkern/gen/OSDebug.cpp
@@ -50,6 +50,9 @@
 extern void kmod_dump_log(vm_offset_t *addr, unsigned int cnt);
 
 extern addr64_t kvtophys(vm_offset_t va);
+#if __arm__
+extern int copyinframe(vm_address_t fp, uint32_t *frame);
+#endif
 
 __END_DECLS
 
@@ -219,6 +222,30 @@
 
     for ( ; frame_index < maxAddrs; frame_index++)
 	    bt[frame_index] = (void *) 0;
+#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;
 #else
 #error arch
 #endif