summaryrefslogtreecommitdiff
path: root/drivers/misc
diff options
context:
space:
mode:
authorIgor Nabirushkin <inabirushkin@nvidia.com>2015-03-21 19:39:55 +0400
committerWinnie Hsu <whsu@nvidia.com>2015-05-29 14:27:50 -0700
commit628479e4e44c3b647d0affefb4c4a1018d8cc44f (patch)
tree12ca92cd36ace03b5032ba3e9d071b85af52097f /drivers/misc
parent8a9b9b0c16211c6ca7977346a56a5f6939e2e273 (diff)
misc: tegra-profiler: fix broken backtraces
Unwinding based on arm32 ehabi: fix broken backtraces when all unwind entries are located in exidx section and extab section is not exist. Bug 1625585 Change-Id: I800e1347b04aa2c2c8802b81478931985c19feb2 Signed-off-by: Igor Nabirushkin <inabirushkin@nvidia.com> Reviewed-on: http://git-master/r/720598 (cherry picked from commit dfc9e9e4ce081b3116e457711e2f4a67fabb169c) Reviewed-on: http://git-master/r/748089 GVS: Gerrit_Virtual_Submit Reviewed-by: Andrey Trachenko <atrachenko@nvidia.com> Reviewed-by: Winnie Hsu <whsu@nvidia.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/tegra-profiler/eh_unwind.c29
-rw-r--r--drivers/misc/tegra-profiler/version.h2
2 files changed, 19 insertions, 12 deletions
diff --git a/drivers/misc/tegra-profiler/eh_unwind.c b/drivers/misc/tegra-profiler/eh_unwind.c
index e3e0955e0bff..11dadb9c4598 100644
--- a/drivers/misc/tegra-profiler/eh_unwind.c
+++ b/drivers/misc/tegra-profiler/eh_unwind.c
@@ -103,14 +103,14 @@ validate_mmap_addr(struct quadd_mmap_area *mmap,
if (addr & 0x03) {
pr_err_once("%s: error: unaligned address: %#lx, data: %#lx-%#lx, vma: %#lx-%#lx\n",
__func__, addr, data, data + size,
- vma->vm_start, vma->vm_end);
+ vma->vm_start, vma->vm_end);
return 0;
}
if (addr < data || addr >= data + (size - nbytes)) {
pr_err_once("%s: error: addr: %#lx, data: %#lx-%#lx, vma: %#lx-%#lx\n",
__func__, addr, data, data + size,
- vma->vm_start, vma->vm_end);
+ vma->vm_start, vma->vm_end);
return 0;
}
@@ -155,8 +155,10 @@ ex_addr_to_mmap_addr(unsigned long addr,
struct extab_info *ti;
ti = &ri->ex_sec[sec_type];
- offset = addr - ti->addr;
+ if (unlikely(!ti->length))
+ return 0;
+ offset = addr - ti->addr;
return ti->mmap_offset + offset + (unsigned long)ri->mmap->data;
}
@@ -169,8 +171,10 @@ mmap_addr_to_ex_addr(unsigned long addr,
struct extab_info *ti;
ti = &ri->ex_sec[sec_type];
- offset = addr - ti->mmap_offset - (unsigned long)ri->mmap->data;
+ if (unlikely(!ti->length))
+ return 0;
+ offset = addr - ti->mmap_offset - (unsigned long)ri->mmap->data;
return ti->addr + offset;
}
@@ -200,6 +204,9 @@ mmap_prel31_to_addr(const u32 *ptr, struct ex_region_info *ri,
offset = (((s32)value) << 1) >> 1;
addr = mmap_addr_to_ex_addr((unsigned long)ptr, ri, src_type);
+ if (unlikely(!addr))
+ return 0;
+
addr += offset;
addr_res = addr;
@@ -361,16 +368,14 @@ static long
get_extabs_ehabi(unsigned long key, struct ex_region_info *ri)
{
long err;
- struct extab_info *ti_extab, *ti_exidx;
+ struct extab_info *ti_exidx;
err = search_ex_region(key, ri);
if (err < 0)
return err;
- ti_extab = &ri->ex_sec[QUADD_SEC_TYPE_EXTAB];
ti_exidx = &ri->ex_sec[QUADD_SEC_TYPE_EXIDX];
-
- return (ti_extab->length && ti_exidx->length) ? 0 : -ENOENT;
+ return ti_exidx->length ? 0 : -ENOENT;
}
long
@@ -664,13 +669,13 @@ unwind_find_idx(struct ex_region_info *ri, u32 addr, unsigned long *lowaddr)
value = (u32)mmap_prel31_to_addr(&start->addr_offset, ri,
QUADD_SEC_TYPE_EXIDX,
QUADD_SEC_TYPE_EXTAB, 0);
- if (addr < value)
+ if (!value || addr < value)
return NULL;
value = (u32)mmap_prel31_to_addr(&stop->addr_offset, ri,
QUADD_SEC_TYPE_EXIDX,
QUADD_SEC_TYPE_EXTAB, 0);
- if (addr >= value)
+ if (!value || addr >= value)
return NULL;
while (start < stop - 1) {
@@ -679,6 +684,8 @@ unwind_find_idx(struct ex_region_info *ri, u32 addr, unsigned long *lowaddr)
value = (u32)mmap_prel31_to_addr(&mid->addr_offset, ri,
QUADD_SEC_TYPE_EXIDX,
QUADD_SEC_TYPE_EXTAB, 0);
+ if (!value)
+ return NULL;
if (addr < value)
stop = mid;
@@ -1018,7 +1025,7 @@ unwind_frame(struct quadd_unw_methods um,
QUADD_SEC_TYPE_EXIDX,
QUADD_SEC_TYPE_EXTAB, 1);
if (!ctrl.insn)
- return -QUADD_URC_EACCESS;
+ return -QUADD_URC_TBL_LINK_INCORRECT;
} else if ((val & 0xff000000) == 0x80000000) {
/* only personality routine 0 supported in the index */
ctrl.insn = &idx->insn;
diff --git a/drivers/misc/tegra-profiler/version.h b/drivers/misc/tegra-profiler/version.h
index c03ad2ff78ec..b5b6ef4c8eee 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.98"
+#define QUADD_MODULE_VERSION "1.99"
#define QUADD_MODULE_BRANCH "Dev"
#endif /* __QUADD_VERSION_H */