asan_linux.cc revision 6895adc39c4e09371154c8037366ad4464163ed0
11e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===-- asan_linux.cc -----------------------------------------------------===//
21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//                     The LLVM Compiler Infrastructure
41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source
61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details.
71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===//
91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker.
111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//
121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Linux-specific details.
131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===//
14d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany#ifdef __linux__
151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
16df499b44de81fc757a789878f07fcaf19ebb0016Kostya Serebryany#include "asan_interceptors.h"
171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h"
18d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany#include "asan_lock.h"
19df499b44de81fc757a789878f07fcaf19ebb0016Kostya Serebryany#include "asan_procmaps.h"
20c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany#include "asan_thread.h"
21ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#include "sanitizer_common/sanitizer_libc.h"
226895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov#include "sanitizer_common/sanitizer_procmaps.h"
231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
24c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany#include <sys/time.h>
25c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany#include <sys/resource.h>
261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <sys/mman.h>
271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <sys/syscall.h>
28de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany#include <sys/types.h>
29de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany#include <fcntl.h>
30c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany#include <pthread.h>
31df499b44de81fc757a789878f07fcaf19ebb0016Kostya Serebryany#include <stdio.h>
321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <unistd.h>
339cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#include <unwind.h>
341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
359107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#ifndef ANDROID
369107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany// FIXME: where to get ucontext on Android?
379107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#include <sys/ucontext.h>
389107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#endif
399107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany
40aa33a50c9d0f3e3f22c8b21fa7309ec91f9d939aEvgeniy Stepanovextern "C" void* _DYNAMIC;
41aa33a50c9d0f3e3f22c8b21fa7309ec91f9d939aEvgeniy Stepanov
421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan {
431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
443f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanyconst uptr kMaxThreadStackSize = 256 * (1 << 20);  // 256M
456f350e0d1c385189cb94ddde7b288a2533b45b32Kostya Serebryany
461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *AsanDoesNotSupportStaticLinkage() {
471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany  // This will fail to link with -static.
48efb3fa36cf421c346e8e54054cdae4fd798edab7Kostya Serebryany  return &_DYNAMIC;  // defined in link.h
491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}
501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany
513f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanyvoid GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
529107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#ifdef ANDROID
539107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany  *pc = *sp = *bp = 0;
549107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#elif defined(__arm__)
559107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany  ucontext_t *ucontext = (ucontext_t*)context;
569107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany  *pc = ucontext->uc_mcontext.arm_pc;
579107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany  *bp = ucontext->uc_mcontext.arm_fp;
589107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany  *sp = ucontext->uc_mcontext.arm_sp;
599107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany# elif defined(__x86_64__)
609107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany  ucontext_t *ucontext = (ucontext_t*)context;
619107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany  *pc = ucontext->uc_mcontext.gregs[REG_RIP];
629107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany  *bp = ucontext->uc_mcontext.gregs[REG_RBP];
639107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany  *sp = ucontext->uc_mcontext.gregs[REG_RSP];
649107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany# elif defined(__i386__)
659107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany  ucontext_t *ucontext = (ucontext_t*)context;
669107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany  *pc = ucontext->uc_mcontext.gregs[REG_EIP];
679107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany  *bp = ucontext->uc_mcontext.gregs[REG_EBP];
689107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany  *sp = ucontext->uc_mcontext.gregs[REG_ESP];
699107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#else
709107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany# error "Unsupported arch"
719107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#endif
729107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany}
739107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany
744803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanybool AsanInterceptsSignal(int signum) {
754803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany  return signum == SIGSEGV && FLAG_handle_segv;
764803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany}
774803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany
783f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanyvoid *AsanMmapFixedNoReserve(uptr fixed_addr, uptr size) {
79ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov  return internal_mmap((void*)fixed_addr, size,
80ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov                      PROT_READ | PROT_WRITE,
81ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov                      MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE,
82ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov                      0, 0);
83a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany}
84a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany
853f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanyvoid *AsanMprotect(uptr fixed_addr, uptr size) {
86ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov  return internal_mmap((void*)fixed_addr, size,
87ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov                       PROT_NONE,
88ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov                       MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE,
89ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov                       0, 0);
90a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany}
91a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany
921e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko// Like getenv, but reads env directly from /proc and does not use libc.
931e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko// This function should be called first inside __asan_init.
941e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenkoconst char* AsanGetEnv(const char* name) {
951e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko  static char *environ;
963f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  static uptr len;
971e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko  static bool inited;
981e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko  if (!inited) {
991e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko    inited = true;
1003f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    uptr environ_size;
1011e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko    len = ReadFileToBuffer("/proc/self/environ",
102160cc4aa34e2418ba91035bb49648e751476f0d9Kostya Serebryany                           &environ, &environ_size, 1 << 26);
1031e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko  }
1043f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  if (!environ || len == 0) return 0;
1053f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  uptr namelen = internal_strlen(name);
1061e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko  const char *p = environ;
1071e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko  while (*p != '\0') {  // will happen at the \0\0 that terminates the buffer
1081e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko    // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
1091e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko    const char* endp =
1101e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko        (char*)internal_memchr(p, '\0', len - (p - environ));
1113f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    if (endp == 0)  // this entry isn't NUL terminated
1123f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany      return 0;
1131e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko    else if (!internal_memcmp(p, name, namelen) && p[namelen] == '=')  // Match.
1141e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko      return p + namelen + 1;  // point after =
1151e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko    p = endp + 1;
1161e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko  }
1173f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  return 0;  // Not found.
1181e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko}
1191e316d7f488a75312539629e9d937e156280eeb6Alexander Potapenko
120c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryanyvoid AsanThread::SetThreadStackTopAndBottom() {
121c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany  if (tid() == 0) {
122c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany    // This is the main thread. Libpthread may not be initialized yet.
123c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany    struct rlimit rl;
124c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany    CHECK(getrlimit(RLIMIT_STACK, &rl) == 0);
125c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany
126c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany    // Find the mapping that contains a stack variable.
1276895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov    ProcessMaps proc_maps;
1283f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    uptr start, end, offset;
1293f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    uptr prev_end = 0;
1303f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    while (proc_maps.Next(&start, &end, &offset, 0, 0)) {
1313f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany      if ((uptr)&rl < end)
132c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany        break;
133c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany      prev_end = end;
134c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany    }
1353f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    CHECK((uptr)&rl >= start && (uptr)&rl < end);
136c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany
137c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany    // Get stacksize from rlimit, but clip it so that it does not overlap
138c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany    // with other mappings.
1393f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    uptr stacksize = rl.rlim_cur;
140c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany    if (stacksize > end - prev_end)
141c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany      stacksize = end - prev_end;
1426f350e0d1c385189cb94ddde7b288a2533b45b32Kostya Serebryany    // When running with unlimited stack size, we still want to set some limit.
1436f350e0d1c385189cb94ddde7b288a2533b45b32Kostya Serebryany    // The unlimited stack size is caused by 'ulimit -s unlimited'.
144ed2341803878f04093f58848468926337d9ca88fDmitry Vyukov    // Also, for some reason, GNU make spawns subprocesses with unlimited stack.
145c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany    if (stacksize > kMaxThreadStackSize)
146c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany      stacksize = kMaxThreadStackSize;
147c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany    stack_top_ = end;
148c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany    stack_bottom_ = end - stacksize;
1493f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany    CHECK(AddrIsInStack((uptr)&rl));
150c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany    return;
151c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany  }
152c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany  pthread_attr_t attr;
153c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany  CHECK(pthread_getattr_np(pthread_self(), &attr) == 0);
1543f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  uptr stacksize = 0;
1553f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  void *stackaddr = 0;
1563f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  pthread_attr_getstack(&attr, &stackaddr, (size_t*)&stacksize);
157c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany  pthread_attr_destroy(&attr);
158c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany
1593f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  stack_top_ = (uptr)stackaddr + stacksize;
1603f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  stack_bottom_ = (uptr)stackaddr;
1616f350e0d1c385189cb94ddde7b288a2533b45b32Kostya Serebryany  CHECK(stacksize < kMaxThreadStackSize);  // Sanity check.
1623f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  CHECK(AddrIsInStack((uptr)&attr));
163c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany}
164c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany
165d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya SerebryanyAsanLock::AsanLock(LinkerInitialized) {
166d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany  // We assume that pthread_mutex_t initialized to all zeroes is a valid
167d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany  // unlocked mutex. We can not use PTHREAD_MUTEX_INITIALIZER as it triggers
168d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany  // a gcc warning:
169d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany  // extended initializer lists only available with -std=c++0x or -std=gnu++0x
170d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany}
171d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany
172d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryanyvoid AsanLock::Lock() {
173d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany  CHECK(sizeof(pthread_mutex_t) <= sizeof(opaque_storage_));
174d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany  pthread_mutex_lock((pthread_mutex_t*)&opaque_storage_);
175d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany  CHECK(!owner_);
1763f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  owner_ = (uptr)pthread_self();
177d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany}
178d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany
179d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryanyvoid AsanLock::Unlock() {
1803f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  CHECK(owner_ == (uptr)pthread_self());
181d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany  owner_ = 0;
182d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany  pthread_mutex_unlock((pthread_mutex_t*)&opaque_storage_);
183d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany}
184d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany
1859cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#ifdef __arm__
1869cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#define UNWIND_STOP _URC_END_OF_STACK
1879cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#define UNWIND_CONTINUE _URC_NO_REASON
1889cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#else
1899cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#define UNWIND_STOP _URC_NORMAL_STOP
1909cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#define UNWIND_CONTINUE _URC_NO_REASON
1919cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#endif
1929cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov
1933f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanyuptr Unwind_GetIP(struct _Unwind_Context *ctx) {
1949cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#ifdef __arm__
1953f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  uptr val;
1969cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  _Unwind_VRS_Result res = _Unwind_VRS_Get(ctx, _UVRSC_CORE,
1979cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov      15 /* r15 = PC */, _UVRSD_UINT32, &val);
1989cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  CHECK(res == _UVRSR_OK && "_Unwind_VRS_Get failed");
1999cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  // Clear the Thumb bit.
2003f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  return val & ~(uptr)1;
2019cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#else
2029cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  return _Unwind_GetIP(ctx);
2039cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#endif
2049cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov}
2059cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov
2069cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx,
2079cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov    void *param) {
2089cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  AsanStackTrace *b = (AsanStackTrace*)param;
2099cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  CHECK(b->size < b->max_size);
2103f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany  uptr pc = Unwind_GetIP(ctx);
2119cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  b->trace[b->size++] = pc;
2129cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  if (b->size == b->max_size) return UNWIND_STOP;
2139cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  return UNWIND_CONTINUE;
2149cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov}
2159cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov
2163f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanyvoid AsanStackTrace::GetStackTrace(uptr max_s, uptr pc, uptr bp) {
2179cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  size = 0;
2189cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  trace[0] = pc;
2199cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  if ((max_s) > 1) {
2209cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov    max_size = max_s;
2219cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#ifdef __arm__
2229cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov    _Unwind_Backtrace(Unwind_Trace, this);
2239cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#else
2249cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov     FastUnwindStack(pc, bp);
2259cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#endif
2269cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov  }
2279cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov}
2289cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov
2291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}  // namespace __asan
230d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany
231d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany#endif  // __linux__
232