misc: tegra-profiler: backtracing for Thumb code
[linux-2.6.git] / drivers / misc / tegra-profiler / backtrace.c
index ea68e98..340f4fa 100644 (file)
@@ -66,7 +66,7 @@ user_backtrace(unsigned long __user *tail,
                return NULL;
 
        if (!check_vma_address(value, stack_vma)) {
-               /* clang's frame */
+               /* gcc thumb/clang frame */
                value_fp = value;
 
                if (check_vma_address((unsigned long)(tail + 1), stack_vma))
@@ -76,7 +76,7 @@ user_backtrace(unsigned long __user *tail,
                                              sizeof(unsigned long)))
                        return NULL;
        } else {
-               /* gcc's frame */
+               /* gcc arm frame */
                if (__copy_from_user_inatomic(&value_fp, tail - 1,
                                              sizeof(unsigned long)))
                        return NULL;
@@ -115,9 +115,10 @@ quadd_get_user_callchain(struct pt_regs *regs,
                return 0;
 
        if (thumb_mode(regs))
-               return 0;
+               fp = regs->ARM_r7;
+       else
+               fp = regs->ARM_fp;
 
-       fp = regs->ARM_fp;
        sp = regs->ARM_sp;
        pc = regs->ARM_pc;
 
@@ -132,8 +133,12 @@ quadd_get_user_callchain(struct pt_regs *regs,
                                      sizeof(unsigned long)))
                return 0;
 
-       if (reg > fp &&
-           !check_vma_address(reg, vma)) {
+       if (thumb_mode(regs)) {
+               if (reg <= fp || check_vma_address(reg, vma))
+                       return 0;
+       } else if (reg > fp &&
+                 !check_vma_address(reg, vma)) {
+               /* fp --> fp prev */
                unsigned long value;
                int read_lr = 0;