[compiler-rt] r217079 - Fix fast stack unwind on ARM to support code generated with GCC.

Chandler Carruth chandlerc at google.com
Wed Sep 3 16:29:50 PDT 2014


I suspect this commit broke the bot:

http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux/builds/12566


On Wed, Sep 3, 2014 at 2:10 PM, Alexey Samsonov <vonosmas at gmail.com> wrote:

> Author: samsonov
> Date: Wed Sep  3 16:10:44 2014
> New Revision: 217079
>
> URL: http://llvm.org/viewvc/llvm-project?rev=217079&view=rev
> Log:
> Fix fast stack unwind on ARM to support code generated with GCC.
>
> http://reviews.llvm.org/D4692
>
> Patch by Maxim Ostapenko!
>
> Added:
>     compiler-rt/trunk/test/asan/TestCases/Linux/clang_gcc_abi.cc
> 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=217079&r1=217078&r2=217079&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.cc Wed
> Sep  3 16:10:44 2014
> @@ -36,19 +36,39 @@ uptr StackTrace::GetCurrentPc() {
>    return GET_CALLER_PC();
>  }
>
> +// Check if given pointer points into allocated stack area.
> +static inline bool IsValidFrame(uptr frame, uptr stack_top, uptr
> stack_bottom) {
> +  return frame > stack_bottom && frame < stack_top - 2 * sizeof (uhwptr);
> +}
> +
> +// In GCC on ARM bp points to saved lr, not fp, so we should check the
> next
> +// cell in stack to be a saved frame pointer. GetCanonicFrame returns the
> +// pointer to saved frame pointer in any case.
> +static inline uhwptr *GetCanonicFrame(uptr bp,
> +                                      uptr stack_top,
> +                                      uptr stack_bottom) {
> +#ifdef __arm__
> +  if (!IsValidFrame(bp, stack_top, stack_bottom)) return 0;
> +  uhwptr *bp_prev = (uhwptr *)bp;
> +  if (IsValidFrame((uptr)bp_prev[0], stack_top, stack_bottom)) return
> bp_prev;
> +  return bp_prev - 1;
> +#else
> +  return (uhwptr*)bp;
> +#endif
> +}
> +
>  void StackTrace::FastUnwindStack(uptr pc, uptr bp,
>                                   uptr stack_top, uptr stack_bottom,
>                                   uptr max_depth) {
>    CHECK_GE(max_depth, 2);
>    trace[0] = pc;
>    size = 1;
> -  uhwptr *frame = (uhwptr *)bp;
> -  uhwptr *prev_frame = frame - 1;
>    if (stack_top < 4096) return;  // Sanity check for stack top.
> +  uhwptr *frame = GetCanonicFrame(bp, stack_top, stack_bottom);
> +  uhwptr *prev_frame = 0;
>    // Avoid infinite loop when frame == frame[0] by using frame >
> prev_frame.
>    while (frame > prev_frame &&
> -         frame < (uhwptr *)stack_top - 2 &&
> -         frame > (uhwptr *)stack_bottom &&
> +         IsValidFrame((uptr)frame, stack_top, stack_bottom) &&
>           IsAligned((uptr)frame, sizeof(*frame)) &&
>           size < max_depth) {
>      uhwptr pc1 = frame[1];
> @@ -56,7 +76,7 @@ void StackTrace::FastUnwindStack(uptr pc
>        trace[size++] = (uptr) pc1;
>      }
>      prev_frame = frame;
> -    frame = (uhwptr *)frame[0];
> +    frame = GetCanonicFrame((uptr)frame[0], stack_top, stack_bottom);
>    }
>  }
>
>
> Added: compiler-rt/trunk/test/asan/TestCases/Linux/clang_gcc_abi.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/clang_gcc_abi.cc?rev=217079&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/test/asan/TestCases/Linux/clang_gcc_abi.cc (added)
> +++ compiler-rt/trunk/test/asan/TestCases/Linux/clang_gcc_abi.cc Wed Sep
> 3 16:10:44 2014
> @@ -0,0 +1,43 @@
> +// RUN: %clangxx_asan -O0 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s
> +// RUN: %clangxx_asan -O1 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s
> +// RUN: %clangxx_asan -O2 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s
> +// RUN: %clangxx_asan -O3 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s
> +
> +// REQUIRES: arm-supported-target
> +
> +#include <stdlib.h>
> +
> +int boom() {
> +  volatile int three = 3;
> +  char *s = (char *)malloc(three);
> +// CHECK: #1 0x{{.*}} in boom {{.*}}clang_gcc_abi.cc:[[@LINE-1]]
> +  return s[three]; //BOOM
> +}
> +
> +__attribute__((naked, noinline)) void gcc_abi() {
> +// CHECK: #2 0x{{.*}} in gcc_abi {{.*}}clang_gcc_abi.cc:[[@LINE+1]]
> +  asm volatile("str fp, [sp, #-8]!\n\t"
> +               "str lr, [sp, #4]\n\t"
> +               "add fp, sp, #4\n\t"
> +               "bl  boom\n\t"
> +               "sub sp, fp, #4\n\t"
> +               "ldr fp, [sp]\n\t"
> +               "add sp, sp, #4\n\t"
> +               "ldr pc, [sp], #4\n\t"
> +              );
> +}
> +
> +__attribute__((naked, noinline)) void clang_abi() {
> +// CHECK: #3 0x{{.*}} in clang_abi {{.*}}clang_gcc_abi.cc:[[@LINE+1]]
> +  asm volatile("push {r11, lr}\n\t"
> +               "mov r11, sp\n\t"
> +               "bl  gcc_abi\n\t"
> +               "add r0, r0, #1\n\t"
> +               "pop {r11, pc}\n\t"
> +              );
> +}
> +
> +int main() {
> +  clang_abi();
> +// CHECK: #4 0x{{.*}} in main {{.*}}clang_gcc_abi.cc:[[@LINE-1]]
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140903/c89fc62a/attachment.html>


More information about the llvm-commits mailing list