2018-08-30 06:23:34 +08:00
|
|
|
//===-- hwasan_thread.h -----------------------------------------*- C++ -*-===//
|
2017-12-09 09:31:51 +08:00
|
|
|
//
|
|
|
|
// 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 HWAddressSanitizer.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef HWASAN_THREAD_H
|
|
|
|
#define HWASAN_THREAD_H
|
|
|
|
|
|
|
|
#include "hwasan_allocator.h"
|
|
|
|
#include "sanitizer_common/sanitizer_common.h"
|
2018-08-30 08:13:20 +08:00
|
|
|
#include "sanitizer_common/sanitizer_thread_registry.h"
|
2017-12-09 09:31:51 +08:00
|
|
|
|
|
|
|
namespace __hwasan {
|
|
|
|
|
2018-08-30 08:13:20 +08:00
|
|
|
class Thread;
|
|
|
|
|
|
|
|
class ThreadContext : public ThreadContextBase {
|
|
|
|
public:
|
|
|
|
explicit ThreadContext(int tid)
|
|
|
|
: ThreadContextBase(tid), thread(nullptr){}
|
|
|
|
|
|
|
|
Thread *thread;
|
|
|
|
|
|
|
|
void OnCreated(void *arg) override;
|
|
|
|
void OnFinished() override;
|
|
|
|
|
|
|
|
struct Args {
|
|
|
|
Thread *thread;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// We want this to be small.
|
|
|
|
COMPILER_CHECK(sizeof(ThreadContext) <= 256);
|
|
|
|
|
|
|
|
class Thread {
|
2017-12-09 09:31:51 +08:00
|
|
|
public:
|
2018-08-30 08:13:20 +08:00
|
|
|
static Thread *Create(thread_callback_t start_routine, void *arg);
|
2017-12-09 09:31:51 +08:00
|
|
|
void Destroy();
|
|
|
|
|
[hwasan] Add a (almost) no-interceptor mode.
Summary:
The idea behind this change is to allow sanitization of libc. We are prototyping on Bionic,
but the tool interface will be general enough (or at least generalizable) to support any other libc.
When libc depends on libclang_rt.hwasan, the latter can not interpose libc functions.
In fact, majority of interceptors become unnecessary when libc code is instrumented.
This change gets rid of most hwasan interceptors and provides interface for libc to notify
hwasan about thread creation and destruction events. Some interceptors (pthread_create)
are kept under #ifdef to enable testing with uninstrumented libc. They are expressed in
terms of the new libc interface.
The new cmake switch, COMPILER_RT_HWASAN_WITH_INTERCEPTORS, ON by default, builds testing
version of the library with the aforementioned pthread_create interceptor.
With the OFF setting, the library becomes more of a libc plugin.
Reviewers: vitalybuka, kcc, jfb
Subscribers: srhines, kubamracek, mgorny, jfb, llvm-commits
Differential Revision: https://reviews.llvm.org/D50922
llvm-svn: 340216
2018-08-21 05:49:15 +08:00
|
|
|
void Init();
|
2017-12-09 09:31:51 +08:00
|
|
|
thread_return_t ThreadStart();
|
|
|
|
|
|
|
|
uptr stack_top() { return stack_top_; }
|
|
|
|
uptr stack_bottom() { return stack_bottom_; }
|
|
|
|
uptr tls_begin() { return tls_begin_; }
|
|
|
|
uptr tls_end() { return tls_end_; }
|
|
|
|
bool IsMainThread() { return start_routine_ == nullptr; }
|
|
|
|
|
|
|
|
bool AddrIsInStack(uptr addr) {
|
|
|
|
return addr >= stack_bottom_ && addr < stack_top_;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool InSignalHandler() { return in_signal_handler_; }
|
|
|
|
void EnterSignalHandler() { in_signal_handler_++; }
|
|
|
|
void LeaveSignalHandler() { in_signal_handler_--; }
|
|
|
|
|
|
|
|
bool InSymbolizer() { return in_symbolizer_; }
|
|
|
|
void EnterSymbolizer() { in_symbolizer_++; }
|
|
|
|
void LeaveSymbolizer() { in_symbolizer_--; }
|
|
|
|
|
|
|
|
bool InInterceptorScope() { return in_interceptor_scope_; }
|
|
|
|
void EnterInterceptorScope() { in_interceptor_scope_++; }
|
|
|
|
void LeaveInterceptorScope() { in_interceptor_scope_--; }
|
|
|
|
|
|
|
|
HwasanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
|
2018-08-30 05:07:07 +08:00
|
|
|
HeapAllocationsRingBuffer *heap_allocations() {
|
|
|
|
return heap_allocations_;
|
|
|
|
}
|
2017-12-09 09:31:51 +08:00
|
|
|
|
2018-08-30 08:13:20 +08:00
|
|
|
void set_context(ThreadContext *context) { context_ = context; }
|
|
|
|
const ThreadContext *context() const { return context_; }
|
|
|
|
|
2018-01-04 05:42:28 +08:00
|
|
|
tag_t GenerateRandomTag();
|
|
|
|
|
2017-12-09 09:31:51 +08:00
|
|
|
int destructor_iterations_;
|
|
|
|
|
|
|
|
private:
|
2018-08-30 08:13:20 +08:00
|
|
|
// NOTE: There is no Thread constructor. It is allocated
|
2017-12-09 09:31:51 +08:00
|
|
|
// via mmap() and *must* be valid in zero-initialized state.
|
|
|
|
void SetThreadStackAndTls();
|
|
|
|
void ClearShadowForThreadStackAndTLS();
|
|
|
|
thread_callback_t start_routine_;
|
|
|
|
void *arg_;
|
|
|
|
uptr stack_top_;
|
|
|
|
uptr stack_bottom_;
|
|
|
|
uptr tls_begin_;
|
|
|
|
uptr tls_end_;
|
|
|
|
|
|
|
|
unsigned in_signal_handler_;
|
|
|
|
unsigned in_symbolizer_;
|
|
|
|
unsigned in_interceptor_scope_;
|
|
|
|
|
2018-01-04 05:42:28 +08:00
|
|
|
u32 random_state_;
|
|
|
|
u32 random_buffer_;
|
|
|
|
|
2017-12-09 09:31:51 +08:00
|
|
|
HwasanThreadLocalMallocStorage malloc_storage_;
|
2018-08-30 05:07:07 +08:00
|
|
|
HeapAllocationsRingBuffer *heap_allocations_;
|
2018-08-30 08:13:20 +08:00
|
|
|
|
|
|
|
u32 tid_;
|
|
|
|
ThreadContext *context_;
|
2017-12-09 09:31:51 +08:00
|
|
|
};
|
|
|
|
|
2018-08-30 08:13:20 +08:00
|
|
|
Thread *GetCurrentThread();
|
|
|
|
void SetCurrentThread(Thread *t);
|
|
|
|
|
|
|
|
// Returns the ThreadRegistry singleton.
|
|
|
|
ThreadRegistry &GetThreadRegistry();
|
|
|
|
|
|
|
|
// Returns the ThreadRegistry singleton.
|
2017-12-09 09:31:51 +08:00
|
|
|
|
|
|
|
} // namespace __hwasan
|
|
|
|
|
|
|
|
#endif // HWASAN_THREAD_H
|