diff options
author | Igor Nabirushkin <inabirushkin@nvidia.com> | 2014-12-02 15:48:47 +0400 |
---|---|---|
committer | Winnie Hsu <whsu@nvidia.com> | 2015-01-29 22:04:47 -0800 |
commit | 35b5c2255719adc77d7dade3da0ad41e55f7d295 (patch) | |
tree | 01c76e70859a8414c2a5178a7da993a210293f85 | |
parent | 091550d652f58ecbb8772e18ef1471ddeb96cc8b (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.c | 50 | ||||
-rw-r--r-- | drivers/misc/tegra-profiler/version.h | 2 |
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 */ |