<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>