summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Nabirushkin <inabirushkin@nvidia.com>2014-12-02 15:48:47 +0400
committerWinnie Hsu <whsu@nvidia.com>2015-01-29 22:04:47 -0800
commit35b5c2255719adc77d7dade3da0ad41e55f7d295 (patch)
tree01c76e70859a8414c2a5178a7da993a210293f85
parent091550d652f58ecbb8772e18ef1471ddeb96cc8b (diff)
misc: tegra-profiler: fix vsp increment
Decode the unwinding instructions (AArch32): fix incorrect increment of virtual stack pointer (vsp). Bug 1584541 Bug 1598009 Change-Id: I4ec64eb21a758b9283df9e6bd6b87a0555180eab Signed-off-by: Igor Nabirushkin <inabirushkin@nvidia.com> Reviewed-on: http://git-master/r/658441 (cherry picked from commit c963ce2532586098ddae159d19a2e241fc25cd1a) Reviewed-on: http://git-master/r/672040 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>
-rw-r--r--drivers/misc/tegra-profiler/eh_unwind.c50
-rw-r--r--drivers/misc/tegra-profiler/version.h2
2 files changed, 46 insertions, 6 deletions
diff --git a/drivers/misc/tegra-profiler/eh_unwind.c b/drivers/misc/tegra-profiler/eh_unwind.c
index 728ca6394f99..a097fd8d1067 100644
--- a/drivers/misc/tegra-profiler/eh_unwind.c
+++ b/drivers/misc/tegra-profiler/eh_unwind.c
@@ -667,6 +667,39 @@ unwind_get_byte(struct quadd_mmap_area *mmap,
return ret;
}
+static long
+read_uleb128(struct quadd_mmap_area *mmap,
+ struct unwind_ctrl_block *ctrl,
+ unsigned long *ret)
+{
+ long err = 0;
+ unsigned long result;
+ unsigned char byte;
+ int shift, count;
+
+ result = 0;
+ shift = 0;
+ count = 0;
+
+ while (1) {
+ byte = unwind_get_byte(mmap, ctrl, &err);
+ if (err < 0)
+ return err;
+
+ count++;
+
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+
+ if (!(byte & 0x80))
+ break;
+ }
+
+ *ret = result;
+
+ return count;
+}
+
/*
* Execute the current unwind instruction.
*/
@@ -790,14 +823,21 @@ unwind_exec_insn(struct quadd_mmap_area *mmap,
ctrl->vrs[SP] = (u32)(unsigned long)vsp;
pr_debug("new vsp: %#x\n", ctrl->vrs[SP]);
} else if (insn == 0xb2) {
- unsigned long uleb128 = unwind_get_byte(mmap, ctrl, &err);
- if (err < 0)
- return err;
+ long count;
+ unsigned long uleb128 = 0;
+
+ count = read_uleb128(mmap, ctrl, &uleb128);
+ if (count < 0)
+ return count;
+
+ if (count == 0)
+ return -QUADD_URC_TBL_IS_CORRUPT;
ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
- pr_debug("CMD_DATA_POP: vsp = vsp + %lu, new vsp: %#x\n",
- 0x204 + (uleb128 << 2), ctrl->vrs[SP]);
+ pr_debug("CMD_DATA_POP: vsp = vsp + %lu (%#lx), new vsp: %#x\n",
+ 0x204 + (uleb128 << 2), 0x204 + (uleb128 << 2),
+ ctrl->vrs[SP]);
} else if (insn == 0xb3 || insn == 0xc8 || insn == 0xc9) {
unsigned long data, reg_from, reg_to;
u32 *vsp = (u32 *)(unsigned long)ctrl->vrs[SP];
diff --git a/drivers/misc/tegra-profiler/version.h b/drivers/misc/tegra-profiler/version.h
index 3836f6683f55..98728a377e37 100644
--- a/drivers/misc/tegra-profiler/version.h
+++ b/drivers/misc/tegra-profiler/version.h
@@ -18,7 +18,7 @@
#ifndef __QUADD_VERSION_H
#define __QUADD_VERSION_H
-#define QUADD_MODULE_VERSION "1.85"
+#define QUADD_MODULE_VERSION "1.86"
#define QUADD_MODULE_BRANCH "Dev"
#endif /* __QUADD_VERSION_H */