diff options
author | Kostya Serebryany <kcc@google.com> | 2012-01-05 01:07:27 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2012-01-05 01:07:27 +0000 |
commit | c549dd7b5fa5fb97270f57067797224cee0429f2 (patch) | |
tree | fee2c866d365d2ab9ecceabeb33ee2a9805352a1 /lib | |
parent | df499b44de81fc757a789878f07fcaf19ebb0016 (diff) | |
download | compiler-rt-c549dd7b5fa5fb97270f57067797224cee0429f2.tar.gz |
[asan] move {linux,mac}-specific code from asan_thread.cc to asan_{linux,mac}.cc; also add asan_procmaps.h which I forgot to add on previous commit.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@147586 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/asan/asan_linux.cc | 52 | ||||
-rw-r--r-- | lib/asan/asan_mac.cc | 10 | ||||
-rw-r--r-- | lib/asan/asan_procmaps.h | 41 | ||||
-rw-r--r-- | lib/asan/asan_thread.cc | 58 |
4 files changed, 103 insertions, 58 deletions
diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cc index 2a529167d..3150f8df9 100644 --- a/lib/asan/asan_linux.cc +++ b/lib/asan/asan_linux.cc @@ -16,11 +16,15 @@ #include "asan_interceptors.h" #include "asan_internal.h" #include "asan_procmaps.h" +#include "asan_thread.h" +#include <sys/time.h> +#include <sys/resource.h> #include <sys/mman.h> #include <sys/syscall.h> #include <sys/types.h> #include <fcntl.h> +#include <pthread.h> #include <stdio.h> #include <unistd.h> @@ -150,6 +154,54 @@ bool AsanProcMaps::Next(uint64_t *start, uint64_t *end, return true; } +void AsanThread::SetThreadStackTopAndBottom() { + if (tid() == 0) { + // This is the main thread. Libpthread may not be initialized yet. + struct rlimit rl; + CHECK(getrlimit(RLIMIT_STACK, &rl) == 0); + + // Find the mapping that contains a stack variable. + AsanProcMaps proc_maps; + uint64_t start, end, offset; + uint64_t prev_end = 0; + while (proc_maps.Next(&start, &end, &offset, NULL, 0)) { + if ((uintptr_t)&rl < end) + break; + prev_end = end; + } + CHECK((uintptr_t)&rl >= start && (uintptr_t)&rl < end); + + // Get stacksize from rlimit, but clip it so that it does not overlap + // with other mappings. + size_t stacksize = rl.rlim_cur; + if (stacksize > end - prev_end) + stacksize = end - prev_end; + if (stacksize > kMaxThreadStackSize) + stacksize = kMaxThreadStackSize; + stack_top_ = end; + stack_bottom_ = end - stacksize; + CHECK(AddrIsInStack((uintptr_t)&rl)); + return; + } + pthread_attr_t attr; + CHECK(pthread_getattr_np(pthread_self(), &attr) == 0); + size_t stacksize = 0; + void *stackaddr = NULL; + pthread_attr_getstack(&attr, &stackaddr, &stacksize); + pthread_attr_destroy(&attr); + + stack_top_ = (uintptr_t)stackaddr + stacksize; + stack_bottom_ = (uintptr_t)stackaddr; + // When running with unlimited stack size, we still want to set some limit. + // The unlimited stack size is caused by 'ulimit -s unlimited'. + // Also, for some reason, GNU make spawns subrocesses with unlimited stack. + if (stacksize > kMaxThreadStackSize) { + stack_bottom_ = stack_top_ - kMaxThreadStackSize; + } + CHECK(AddrIsInStack((uintptr_t)&attr)); +} + + } // namespace __asan #endif // __linux__ diff --git a/lib/asan/asan_mac.cc b/lib/asan/asan_mac.cc index b202e639b..8bedf7aaa 100644 --- a/lib/asan/asan_mac.cc +++ b/lib/asan/asan_mac.cc @@ -22,6 +22,7 @@ #include "asan_thread_registry.h" #include <sys/mman.h> +#include <pthread.h> #include <fcntl.h> #include <unistd.h> @@ -103,6 +104,15 @@ int AsanClose(int fd) { return close(fd); } +void AsanThread::SetThreadStackTopAndBottom() { + size_t stacksize = pthread_get_stacksize_np(pthread_self()); + void *stackaddr = pthread_get_stackaddr_np(pthread_self()); + stack_top_ = (uintptr_t)stackaddr; + stack_bottom_ = stack_top_ - stacksize; + int local; + CHECK(AddrIsInStack((uintptr_t)&local)); +} + // Support for the following functions from libdispatch on Mac OS: // dispatch_async_f() // dispatch_async() diff --git a/lib/asan/asan_procmaps.h b/lib/asan/asan_procmaps.h new file mode 100644 index 000000000..48ab58ae8 --- /dev/null +++ b/lib/asan/asan_procmaps.h @@ -0,0 +1,41 @@ +//===-- asan_process.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Information about the process mappings. +//===----------------------------------------------------------------------===// +#ifndef ASAN_PROCMAPS_H +#define ASAN_PROCMAPS_H + +#include "asan_internal.h" + +namespace __asan { + +class AsanProcMaps { + public: + AsanProcMaps(); + bool Next(uint64_t *start, uint64_t *end, uint64_t *offset, + char filename[], size_t filename_size); + void Reset(); + ~AsanProcMaps(); + private: +#if defined __linux__ + char *proc_self_maps_buff_; + size_t proc_self_maps_buff_mmaped_size_; + size_t proc_self_maps_buff_len_; + char *current_; +#elif defined __APPLE__ +// FIXME: Mac code goes here +#endif +}; + +} // namespace __asan + +#endif // ASAN_PROCMAPS_H diff --git a/lib/asan/asan_thread.cc b/lib/asan/asan_thread.cc index 420c34273..6fa330173 100644 --- a/lib/asan/asan_thread.cc +++ b/lib/asan/asan_thread.cc @@ -18,8 +18,6 @@ #include "asan_thread_registry.h" #include "asan_mapping.h" -#include <sys/time.h> -#include <sys/resource.h> #include <pthread.h> #include <stdlib.h> #include <string.h> @@ -114,60 +112,4 @@ const char *AsanThread::GetFrameNameByAddr(uintptr_t addr, uintptr_t *offset) { return "UNKNOWN"; } -void AsanThread::SetThreadStackTopAndBottom() { -#ifdef __APPLE__ - size_t stacksize = pthread_get_stacksize_np(pthread_self()); - void *stackaddr = pthread_get_stackaddr_np(pthread_self()); - stack_top_ = (uintptr_t)stackaddr; - stack_bottom_ = stack_top_ - stacksize; - int local; - CHECK(AddrIsInStack((uintptr_t)&local)); -#else - if (tid() == 0) { - // This is the main thread. Libpthread may not be initialized yet. - struct rlimit rl; - CHECK(getrlimit(RLIMIT_STACK, &rl) == 0); - - // Find the mapping that contains a stack variable. - AsanProcMaps proc_maps; - uint64_t start, end, offset; - uint64_t prev_end = 0; - while (proc_maps.Next(&start, &end, &offset, NULL, 0)) { - if ((uintptr_t)&rl < end) - break; - prev_end = end; - } - CHECK((uintptr_t)&rl >= start && (uintptr_t)&rl < end); - - // Get stacksize from rlimit, but clip it so that it does not overlap - // with other mappings. - size_t stacksize = rl.rlim_cur; - if (stacksize > end - prev_end) - stacksize = end - prev_end; - if (stacksize > kMaxThreadStackSize) - stacksize = kMaxThreadStackSize; - stack_top_ = end; - stack_bottom_ = end - stacksize; - CHECK(AddrIsInStack((uintptr_t)&rl)); - return; - } - pthread_attr_t attr; - CHECK(pthread_getattr_np(pthread_self(), &attr) == 0); - size_t stacksize = 0; - void *stackaddr = NULL; - pthread_attr_getstack(&attr, &stackaddr, &stacksize); - pthread_attr_destroy(&attr); - - stack_top_ = (uintptr_t)stackaddr + stacksize; - stack_bottom_ = (uintptr_t)stackaddr; - // When running with unlimited stack size, we still want to set some limit. - // The unlimited stack size is caused by 'ulimit -s unlimited'. - // Also, for some reason, GNU make spawns subrocesses with unlimited stack. - if (stacksize > kMaxThreadStackSize) { - stack_bottom_ = stack_top_ - kMaxThreadStackSize; - } - CHECK(AddrIsInStack((uintptr_t)&attr)); -#endif -} - } // namespace __asan |