summaryrefslogtreecommitdiff
path: root/libsanitizer/sanitizer_common
diff options
context:
space:
mode:
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>2015-07-29 03:33:10 +0000
committerWilliam Schmidt <wschmidt@gcc.gnu.org>2015-07-29 03:33:10 +0000
commit3d61d8758577f5bf9ce4884544cbbc09af71ca28 (patch)
treec120873d10258dab0ff7f2e777e48a63a8f1b010 /libsanitizer/sanitizer_common
parentc73858e98250fa26e21676c30c4ac4bce241d626 (diff)
downloadgcc-3d61d8758577f5bf9ce4884544cbbc09af71ca28.tar.gz
re PR sanitizer/63927 (AddressSanitizer painfully slow on ppc64)
2015-07-28 Bill Schmidt <wschmidt@linux.vnet.ibm.com> PR sanitizer/63927 * sanitizer_common/sanitizer_stacktrace.cc (BufferedStackTrace::FastUnwindStack): Fix code for PowerPC to find the link register at an offset of 16 from the base of the caller's stack frame. From-SVN: r226335
Diffstat (limited to 'libsanitizer/sanitizer_common')
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stacktrace.cc11
1 files changed, 11 insertions, 0 deletions
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
index 9b99b5bb201..a751da2f740 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
@@ -86,7 +86,18 @@ void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top,
while (IsValidFrame((uptr)frame, stack_top, bottom) &&
IsAligned((uptr)frame, sizeof(*frame)) &&
size < max_depth) {
+#ifdef __powerpc__
+ // PowerPC ABIs specify that the return address is saved at offset
+ // 16 of the *caller's* stack frame. Thus we must dereference the
+ // back chain to find the caller frame before extracting it.
+ uhwptr *caller_frame = (uhwptr*)frame[0];
+ if (!IsValidFrame((uptr)caller_frame, stack_top, bottom) ||
+ !IsAligned((uptr)caller_frame, sizeof(uhwptr)))
+ break;
+ uhwptr pc1 = caller_frame[2];
+#else
uhwptr pc1 = frame[1];
+#endif
if (pc1 != pc) {
trace_buffer[size++] = (uptr) pc1;
}