]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR sanitizer/63927 (AddressSanitizer painfully slow on ppc64)
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Wed, 29 Jul 2015 03:33:10 +0000 (03:33 +0000)
committerWilliam Schmidt <wschmidt@gcc.gnu.org>
Wed, 29 Jul 2015 03:33:10 +0000 (03:33 +0000)
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

libsanitizer/ChangeLog
libsanitizer/sanitizer_common/sanitizer_stacktrace.cc

index 84147bfb2e58cfa94be8f1ff304aefce6efae485..94a9531497b4e989fcedb12c3356e2707c4525c7 100644 (file)
@@ -1,3 +1,11 @@
+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.
+
 2015-05-13  Michael Haubenwallner  <michael.haubenwallner@ssi-schaefer.com>
 
        * Makefile.in: Regenerated with automake-1.11.6.
index 9b99b5bb201e3236a18f8735495e5b5bbe352efd..a751da2f740400dc70d064075eb7dd15994790da 100644 (file)
@@ -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;
     }