<div dir="ltr">I suspect this commit broke the bot:<div><br></div><div><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux/builds/12566">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux/builds/12566</a><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Sep 3, 2014 at 2:10 PM, Alexey Samsonov <span dir="ltr"><<a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: samsonov<br>
Date: Wed Sep  3 16:10:44 2014<br>
New Revision: 217079<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=217079&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=217079&view=rev</a><br>
Log:<br>
Fix fast stack unwind on ARM to support code generated with GCC.<br>
<br>
<a href="http://reviews.llvm.org/D4692" target="_blank">http://reviews.llvm.org/D4692</a><br>
<br>
Patch by Maxim Ostapenko!<br>
<br>
Added:<br>
    compiler-rt/trunk/test/asan/TestCases/Linux/clang_gcc_abi.cc<br>
Modified:<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc?rev=217079&r1=217078&r2=217079&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc?rev=217079&r1=217078&r2=217079&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc Wed Sep  3 16:10:44 2014<br>
@@ -36,19 +36,39 @@ uptr StackTrace::GetCurrentPc() {<br>
   return GET_CALLER_PC();<br>
 }<br>
<br>
+// Check if given pointer points into allocated stack area.<br>
+static inline bool IsValidFrame(uptr frame, uptr stack_top, uptr stack_bottom) {<br>
+  return frame > stack_bottom && frame < stack_top - 2 * sizeof (uhwptr);<br>
+}<br>
+<br>
+// In GCC on ARM bp points to saved lr, not fp, so we should check the next<br>
+// cell in stack to be a saved frame pointer. GetCanonicFrame returns the<br>
+// pointer to saved frame pointer in any case.<br>
+static inline uhwptr *GetCanonicFrame(uptr bp,<br>
+                                      uptr stack_top,<br>
+                                      uptr stack_bottom) {<br>
+#ifdef __arm__<br>
+  if (!IsValidFrame(bp, stack_top, stack_bottom)) return 0;<br>
+  uhwptr *bp_prev = (uhwptr *)bp;<br>
+  if (IsValidFrame((uptr)bp_prev[0], stack_top, stack_bottom)) return bp_prev;<br>
+  return bp_prev - 1;<br>
+#else<br>
+  return (uhwptr*)bp;<br>
+#endif<br>
+}<br>
+<br>
 void StackTrace::FastUnwindStack(uptr pc, uptr bp,<br>
                                  uptr stack_top, uptr stack_bottom,<br>
                                  uptr max_depth) {<br>
   CHECK_GE(max_depth, 2);<br>
   trace[0] = pc;<br>
   size = 1;<br>
-  uhwptr *frame = (uhwptr *)bp;<br>
-  uhwptr *prev_frame = frame - 1;<br>
   if (stack_top < 4096) return;  // Sanity check for stack top.<br>
+  uhwptr *frame = GetCanonicFrame(bp, stack_top, stack_bottom);<br>
+  uhwptr *prev_frame = 0;<br>
   // Avoid infinite loop when frame == frame[0] by using frame > prev_frame.<br>
   while (frame > prev_frame &&<br>
-         frame < (uhwptr *)stack_top - 2 &&<br>
-         frame > (uhwptr *)stack_bottom &&<br>
+         IsValidFrame((uptr)frame, stack_top, stack_bottom) &&<br>
          IsAligned((uptr)frame, sizeof(*frame)) &&<br>
          size < max_depth) {<br>
     uhwptr pc1 = frame[1];<br>
@@ -56,7 +76,7 @@ void StackTrace::FastUnwindStack(uptr pc<br>
       trace[size++] = (uptr) pc1;<br>
     }<br>
     prev_frame = frame;<br>
-    frame = (uhwptr *)frame[0];<br>
+    frame = GetCanonicFrame((uptr)frame[0], stack_top, stack_bottom);<br>
   }<br>
 }<br>
<br>
<br>
Added: compiler-rt/trunk/test/asan/TestCases/Linux/clang_gcc_abi.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/clang_gcc_abi.cc?rev=217079&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/clang_gcc_abi.cc?rev=217079&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/test/asan/TestCases/Linux/clang_gcc_abi.cc (added)<br>
+++ compiler-rt/trunk/test/asan/TestCases/Linux/clang_gcc_abi.cc Wed Sep  3 16:10:44 2014<br>
@@ -0,0 +1,43 @@<br>
+// RUN: %clangxx_asan -O0 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s<br>
+// RUN: %clangxx_asan -O1 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s<br>
+// RUN: %clangxx_asan -O2 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s<br>
+// RUN: %clangxx_asan -O3 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s<br>
+<br>
+// REQUIRES: arm-supported-target<br>
+<br>
+#include <stdlib.h><br>
+<br>
+int boom() {<br>
+  volatile int three = 3;<br>
+  char *s = (char *)malloc(three);<br>
+// CHECK: #1 0x{{.*}} in boom {{.*}}clang_gcc_abi.cc:[[@LINE-1]]<br>
+  return s[three]; //BOOM<br>
+}<br>
+<br>
+__attribute__((naked, noinline)) void gcc_abi() {<br>
+// CHECK: #2 0x{{.*}} in gcc_abi {{.*}}clang_gcc_abi.cc:[[@LINE+1]]<br>
+  asm volatile("str fp, [sp, #-8]!\n\t"<br>
+               "str lr, [sp, #4]\n\t"<br>
+               "add fp, sp, #4\n\t"<br>
+               "bl  boom\n\t"<br>
+               "sub sp, fp, #4\n\t"<br>
+               "ldr fp, [sp]\n\t"<br>
+               "add sp, sp, #4\n\t"<br>
+               "ldr pc, [sp], #4\n\t"<br>
+              );<br>
+}<br>
+<br>
+__attribute__((naked, noinline)) void clang_abi() {<br>
+// CHECK: #3 0x{{.*}} in clang_abi {{.*}}clang_gcc_abi.cc:[[@LINE+1]]<br>
+  asm volatile("push {r11, lr}\n\t"<br>
+               "mov r11, sp\n\t"<br>
+               "bl  gcc_abi\n\t"<br>
+               "add r0, r0, #1\n\t"<br>
+               "pop {r11, pc}\n\t"<br>
+              );<br>
+}<br>
+<br>
+int main() {<br>
+  clang_abi();<br>
+// CHECK: #4 0x{{.*}} in main {{.*}}clang_gcc_abi.cc:[[@LINE-1]]<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>