[compiler-rt] r297995 - [PowerPC] Fix sanitizer frame unwind on 32-bit ABIs

Bill Seurer via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 16 14:14:14 PDT 2017


Author: seurer
Date: Thu Mar 16 16:14:13 2017
New Revision: 297995

URL: http://llvm.org/viewvc/llvm-project?rev=297995&view=rev
Log:
[PowerPC] Fix sanitizer frame unwind on 32-bit ABIs

This fixes many sanitizer problems with -m32.  It is really intended
for gcc but patches to the sanitizers make their way through llvm
first.

ref:  https://gcc.gnu.org/ml/gcc-patches/2017-02/msg00855.html

Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc?rev=297995&r1=297994&r2=297995&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc Thu Mar 16 16:14:13 2017
@@ -79,15 +79,22 @@ void BufferedStackTrace::FastUnwindStack
   while (IsValidFrame((uptr)frame, stack_top, bottom) &&
          IsAligned((uptr)frame, sizeof(*frame)) &&
          size < max_depth) {
+     // PowerPC ABIs specify that the return address is saved on 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;
 #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;
+    // For most ABIs the offset where the return address is saved is two
+    // register sizes.  The exception is the SVR4 ABI, which uses an
+    // offset of only one register size.
+#ifdef _CALL_SYSV
+    uhwptr pc1 = caller_frame[1];
+#else
     uhwptr pc1 = caller_frame[2];
+#endif
 #elif defined(__s390__)
     uhwptr pc1 = frame[14];
 #else




More information about the llvm-commits mailing list