summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2012-06-07 07:13:46 +0000
committerAlexey Samsonov <samsonov@google.com>2012-06-07 07:13:46 +0000
commite5931fd7d2a74fd7fb60bd8d7f644cca51a24364 (patch)
treebed59375675460fe548790ea6672c9a5ba91d641 /lib
parent6895adc39c4e09371154c8037366ad4464163ed0 (diff)
downloadcompiler-rt-e5931fd7d2a74fd7fb60bd8d7f644cca51a24364.tar.gz
[Sanitizer] factor out GetThreadStackTopAndBottom from ASan runtime to common.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@158140 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/asan/asan_linux.cc45
-rw-r--r--lib/asan/asan_mac.cc9
-rw-r--r--lib/asan/asan_thread.cc7
-rw-r--r--lib/asan/asan_win.cc11
-rw-r--r--lib/sanitizer_common/sanitizer_common.h5
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc54
-rw-r--r--lib/sanitizer_common/sanitizer_mac.cc20
-rw-r--r--lib/sanitizer_common/sanitizer_win.cc16
8 files changed, 98 insertions, 69 deletions
diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cc
index 947c17f70..b3f879b52 100644
--- a/lib/asan/asan_linux.cc
+++ b/lib/asan/asan_linux.cc
@@ -117,51 +117,6 @@ const char* AsanGetEnv(const char* name) {
return 0; // Not found.
}
-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.
- ProcessMaps proc_maps;
- uptr start, end, offset;
- uptr prev_end = 0;
- while (proc_maps.Next(&start, &end, &offset, 0, 0)) {
- if ((uptr)&rl < end)
- break;
- prev_end = end;
- }
- CHECK((uptr)&rl >= start && (uptr)&rl < end);
-
- // Get stacksize from rlimit, but clip it so that it does not overlap
- // with other mappings.
- uptr stacksize = rl.rlim_cur;
- if (stacksize > end - prev_end)
- stacksize = end - prev_end;
- // 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 subprocesses with unlimited stack.
- if (stacksize > kMaxThreadStackSize)
- stacksize = kMaxThreadStackSize;
- stack_top_ = end;
- stack_bottom_ = end - stacksize;
- CHECK(AddrIsInStack((uptr)&rl));
- return;
- }
- pthread_attr_t attr;
- CHECK(pthread_getattr_np(pthread_self(), &attr) == 0);
- uptr stacksize = 0;
- void *stackaddr = 0;
- pthread_attr_getstack(&attr, &stackaddr, (size_t*)&stacksize);
- pthread_attr_destroy(&attr);
-
- stack_top_ = (uptr)stackaddr + stacksize;
- stack_bottom_ = (uptr)stackaddr;
- CHECK(stacksize < kMaxThreadStackSize); // Sanity check.
- CHECK(AddrIsInStack((uptr)&attr));
-}
-
AsanLock::AsanLock(LinkerInitialized) {
// We assume that pthread_mutex_t initialized to all zeroes is a valid
// unlocked mutex. We can not use PTHREAD_MUTEX_INITIALIZER as it triggers
diff --git a/lib/asan/asan_mac.cc b/lib/asan/asan_mac.cc
index 644fbd9af..a2df818c5 100644
--- a/lib/asan/asan_mac.cc
+++ b/lib/asan/asan_mac.cc
@@ -132,15 +132,6 @@ const char *AsanGetEnv(const char *name) {
return 0;
}
-void AsanThread::SetThreadStackTopAndBottom() {
- uptr stacksize = pthread_get_stacksize_np(pthread_self());
- void *stackaddr = pthread_get_stackaddr_np(pthread_self());
- stack_top_ = (uptr)stackaddr;
- stack_bottom_ = stack_top_ - stacksize;
- int local;
- CHECK(AddrIsInStack((uptr)&local));
-}
-
AsanLock::AsanLock(LinkerInitialized) {
// We assume that OS_SPINLOCK_INIT is zero
}
diff --git a/lib/asan/asan_thread.cc b/lib/asan/asan_thread.cc
index da397bb5b..d301a4b87 100644
--- a/lib/asan/asan_thread.cc
+++ b/lib/asan/asan_thread.cc
@@ -18,6 +18,7 @@
#include "asan_thread.h"
#include "asan_thread_registry.h"
#include "asan_mapping.h"
+#include "sanitizer_common/sanitizer_common.h"
namespace __asan {
@@ -101,6 +102,12 @@ thread_return_t AsanThread::ThreadStart() {
return res;
}
+void AsanThread::SetThreadStackTopAndBottom() {
+ GetThreadStackTopAndBottom(tid() == 0, &stack_top_, &stack_bottom_);
+ int local;
+ CHECK(AddrIsInStack((uptr)&local));
+}
+
void AsanThread::ClearShadowForThreadStack() {
PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0);
}
diff --git a/lib/asan/asan_win.cc b/lib/asan/asan_win.cc
index 3ec75f912..ad62535fa 100644
--- a/lib/asan/asan_win.cc
+++ b/lib/asan/asan_win.cc
@@ -47,17 +47,6 @@ static AsanLock dbghelp_lock(LINKER_INITIALIZED);
static bool dbghelp_initialized = false;
#pragma comment(lib, "dbghelp.lib")
-void AsanThread::SetThreadStackTopAndBottom() {
- MEMORY_BASIC_INFORMATION mbi;
- CHECK(VirtualQuery(&mbi /* on stack */,
- &mbi, sizeof(mbi)) != 0);
- // FIXME: is it possible for the stack to not be a single allocation?
- // Are these values what ASan expects to get (reserved, not committed;
- // including stack guard page) ?
- stack_top_ = (uptr)mbi.BaseAddress + mbi.RegionSize;
- stack_bottom_ = (uptr)mbi.AllocationBase;
-}
-
void AsanStackTrace::GetStackTrace(uptr max_s, uptr pc, uptr bp) {
max_size = max_s;
void *tmp[kStackTraceMax];
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h
index 2f13814bc..817b95903 100644
--- a/lib/sanitizer_common/sanitizer_common.h
+++ b/lib/sanitizer_common/sanitizer_common.h
@@ -26,13 +26,16 @@ const uptr kWordSizeInBits = 8 * kWordSize;
const uptr kPageSizeBits = 12;
const uptr kPageSize = 1UL << kPageSizeBits;
+// Threads
int GetPid();
-void RawWrite(const char *buffer);
+void GetThreadStackTopAndBottom(bool is_main_thread, uptr *stack_top,
+ uptr *stack_bottom);
// Memory management
void *MmapOrDie(uptr size, const char *mem_type);
void UnmapOrDie(void *addr, uptr size);
+void RawWrite(const char *buffer);
void Printf(const char *format, ...);
int SNPrintf(char *buffer, uptr length, const char *format, ...);
void Report(const char *format, ...);
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 9cd336efe..1ece95c62 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -19,14 +19,18 @@
#include "sanitizer_procmaps.h"
#include <fcntl.h>
+#include <pthread.h>
#include <sys/mman.h>
+#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/syscall.h>
+#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
namespace __sanitizer {
+// --------------- sanitizer_libc.h
void *internal_mmap(void *addr, uptr length, int prot, int flags,
int fd, u64 offset) {
#if __WORDSIZE == 64
@@ -68,7 +72,55 @@ int internal_dup2(int oldfd, int newfd) {
return syscall(__NR_dup2, oldfd, newfd);
}
-// ----------------- ProcessMaps implementation.
+// ----------------- sanitizer_common.h
+void GetThreadStackTopAndBottom(bool is_main_thread, uptr *stack_top,
+ uptr *stack_bottom) {
+ static const uptr kMaxThreadStackSize = 256 * (1 << 20); // 256M
+ CHECK(stack_top);
+ CHECK(stack_bottom);
+ if (is_main_thread) {
+ // 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.
+ ProcessMaps proc_maps;
+ uptr start, end, offset;
+ uptr prev_end = 0;
+ while (proc_maps.Next(&start, &end, &offset, 0, 0)) {
+ if ((uptr)&rl < end)
+ break;
+ prev_end = end;
+ }
+ CHECK((uptr)&rl >= start && (uptr)&rl < end);
+
+ // Get stacksize from rlimit, but clip it so that it does not overlap
+ // with other mappings.
+ uptr stacksize = rl.rlim_cur;
+ if (stacksize > end - prev_end)
+ stacksize = end - prev_end;
+ // 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 subprocesses with unlimited stack.
+ if (stacksize > kMaxThreadStackSize)
+ stacksize = kMaxThreadStackSize;
+ *stack_top = end;
+ *stack_bottom = end - stacksize;
+ return;
+ }
+ pthread_attr_t attr;
+ CHECK(pthread_getattr_np(pthread_self(), &attr) == 0);
+ uptr stacksize = 0;
+ void *stackaddr = 0;
+ pthread_attr_getstack(&attr, &stackaddr, (size_t*)&stacksize);
+ pthread_attr_destroy(&attr);
+
+ *stack_top = (uptr)stackaddr + stacksize;
+ *stack_bottom = (uptr)stackaddr;
+ CHECK(stacksize < kMaxThreadStackSize); // Sanity check.
+}
+
+// ----------------- sanitizer_procmaps.h
ProcessMaps::ProcessMaps() {
proc_self_maps_buff_len_ =
ReadFileToBuffer("/proc/self/maps", &proc_self_maps_buff_,
diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc
index 6fe0b6086..d0f334082 100644
--- a/lib/sanitizer_common/sanitizer_mac.cc
+++ b/lib/sanitizer_common/sanitizer_mac.cc
@@ -14,20 +14,24 @@
#ifdef __APPLE__
+#include "sanitizer_common.h"
#include "sanitizer_internal_defs.h"
#include "sanitizer_libc.h"
#include "sanitizer_procmaps.h"
+#include <fcntl.h>
#include <mach-o/dyld.h>
#include <mach-o/loader.h>
+#include <pthread.h>
#include <sys/mman.h>
+#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <fcntl.h>
#include <unistd.h>
namespace __sanitizer {
+// ---------------------- sanitizer_libc.h
void *internal_mmap(void *addr, size_t length, int prot, int flags,
int fd, u64 offset) {
return mmap(addr, length, prot, flags, fd, offset);
@@ -65,7 +69,19 @@ int internal_dup2(int oldfd, int newfd) {
return dup2(oldfd, newfd);
}
-// ----------------- ProcessMaps implementation.
+// ----------------- sanitizer_common.h
+void GetThreadStackTopAndBottom(bool is_main_thread, uptr *stack_top,
+ uptr *stack_bottom) {
+ CHECK(stack_top);
+ CHECK(stack_bottom);
+ uptr stacksize = pthread_get_stacksize_np(pthread_self());
+ void *stackaddr = pthread_get_stackaddr_np(pthread_self());
+ *stack_top = (uptr)stackaddr;
+ *stack_bottom = stack_top_ - stacksize;
+}
+
+
+// ----------------- sanitizer_procmaps.h
ProcessMaps::ProcessMaps() {
Reset();
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc
index db16d857d..6c8ed41ab 100644
--- a/lib/sanitizer_common/sanitizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_win.cc
@@ -19,10 +19,25 @@
namespace __sanitizer {
+// --------------------- sanitizer_common.h
int GetPid() {
return GetProcessId(GetCurrentProcess());
}
+void GetThreadStackTopAndBottom(bool is_main_thread, uptr *stack_top,
+ uptr *stack_bottom) {
+ CHECK(stack_top);
+ CHECK(stack_bottom);
+ MEMORY_BASIC_INFORMATION mbi;
+ CHECK(VirtualQuery(&mbi /* on stack */, &mbi, sizeof(mbi)) != 0);
+ // FIXME: is it possible for the stack to not be a single allocation?
+ // Are these values what ASan expects to get (reserved, not committed;
+ // including stack guard page) ?
+ *stack_top = (uptr)mbi.BaseAddress + mbi.RegionSize;
+ *stack_bottom = (uptr)mbi.AllocationBase;
+}
+
+
void *MmapOrDie(uptr size, const char *mem_type) {
void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (rv == 0) {
@@ -41,6 +56,7 @@ void UnmapOrDie(void *addr, uptr size) {
}
}
+// ------------------ sanitizer_libc.h
void *internal_mmap(void *addr, uptr length, int prot, int flags,
int fd, u64 offset) {
UNIMPLEMENTED();