summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sanitizer_common')
-rw-r--r--lib/sanitizer_common/sanitizer_common.h32
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc6
-rw-r--r--lib/sanitizer_common/sanitizer_mac.cc6
-rw-r--r--lib/sanitizer_common/sanitizer_posix.cc15
-rw-r--r--lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc2
-rw-r--r--lib/sanitizer_common/sanitizer_win.cc43
6 files changed, 60 insertions, 44 deletions
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h
index 6cd21d79a..51c1f3575 100644
--- a/lib/sanitizer_common/sanitizer_common.h
+++ b/lib/sanitizer_common/sanitizer_common.h
@@ -801,41 +801,39 @@ struct SignalContext {
uptr sp;
uptr bp;
bool is_memory_access;
-
enum WriteFlag { UNKNOWN, READ, WRITE } write_flag;
// VS2013 doesn't implement unrestricted unions, so we need a trivial default
// constructor
SignalContext() = default;
+
+ // Creates signal context in a platform-specific manner.
// SignalContext is going to keep pointers to siginfo and context without
// owning them.
- SignalContext(void *siginfo, void *context, uptr addr, uptr pc, uptr sp,
- uptr bp, bool is_memory_access, WriteFlag write_flag)
+ SignalContext(void *siginfo, void *context)
: siginfo(siginfo),
context(context),
- addr(addr),
- pc(pc),
- sp(sp),
- bp(bp),
- is_memory_access(is_memory_access),
- write_flag(write_flag) {}
+ addr(GetAddress()),
+ is_memory_access(IsMemoryAccess()),
+ write_flag(GetWriteFlag()) {
+ InitPcSpBp();
+ }
static void DumpAllRegisters(void *context);
- // Creates signal context in a platform-specific manner.
- static SignalContext Create(void *siginfo, void *context);
-
- // Returns true if the "context" indicates a memory write.
- static WriteFlag GetWriteFlag(void *context);
-
// Type of signal e.g. SIGSEGV or EXCEPTION_ACCESS_VIOLATION.
int GetType() const;
// String description of the signal.
const char *Describe() const;
-};
-void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp);
+ private:
+ // Platform specific initialization.
+ void InitPcSpBp();
+ uptr GetAddress() const;
+ WriteFlag GetWriteFlag() const;
+ bool IsMemoryAccess() const;
+};
void MaybeReexec();
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 7923078a6..72d53e826 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -1628,7 +1628,7 @@ static bool Aarch64GetESR(ucontext_t *ucontext, u64 *esr) {
}
#endif
-SignalContext::WriteFlag SignalContext::GetWriteFlag(void *context) {
+SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
ucontext_t *ucontext = (ucontext_t *)context;
#if defined(__x86_64__) || defined(__i386__)
static const uptr PF_WRITE = 1U << 1;
@@ -1659,7 +1659,7 @@ void SignalContext::DumpAllRegisters(void *context) {
// FIXME: Implement this.
}
-void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
+static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
#if defined(__arm__)
ucontext_t *ucontext = (ucontext_t*)context;
*pc = ucontext->uc_mcontext.arm_pc;
@@ -1750,6 +1750,8 @@ void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
#endif
}
+void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); }
+
void MaybeReexec() {
// No need to re-exec on Linux.
}
diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc
index 6cb75266b..1570ae277 100644
--- a/lib/sanitizer_common/sanitizer_mac.cc
+++ b/lib/sanitizer_common/sanitizer_mac.cc
@@ -574,7 +574,7 @@ void LogFullErrorReport(const char *buffer) {
#endif
}
-SignalContext::WriteFlag SignalContext::GetWriteFlag(void *context) {
+SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
#if defined(__x86_64__) || defined(__i386__)
ucontext_t *ucontext = static_cast<ucontext_t*>(context);
return ucontext->uc_mcontext->__es.__err & 2 /*T_PF_WRITE*/ ? WRITE : READ;
@@ -583,7 +583,7 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag(void *context) {
#endif
}
-void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
+static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
ucontext_t *ucontext = (ucontext_t*)context;
# if defined(__aarch64__)
*pc = ucontext->uc_mcontext->__ss.__pc;
@@ -610,6 +610,8 @@ void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
# endif
}
+void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); }
+
#if !SANITIZER_GO
static const char kDyldInsertLibraries[] = "DYLD_INSERT_LIBRARIES";
LowLevelAllocator allocator_for_env;
diff --git a/lib/sanitizer_common/sanitizer_posix.cc b/lib/sanitizer_common/sanitizer_posix.cc
index 35fc35ce9..1fad71f35 100644
--- a/lib/sanitizer_common/sanitizer_posix.cc
+++ b/lib/sanitizer_common/sanitizer_posix.cc
@@ -295,15 +295,14 @@ bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) {
return false;
}
-SignalContext SignalContext::Create(void *siginfo, void *context) {
+uptr SignalContext::GetAddress() const {
auto si = static_cast<const siginfo_t *>(siginfo);
- uptr addr = (uptr)si->si_addr;
- uptr pc, sp, bp;
- GetPcSpBp(context, &pc, &sp, &bp);
- WriteFlag write_flag = GetWriteFlag(context);
- bool is_memory_access = si->si_signo == SIGSEGV;
- return SignalContext(siginfo, context, addr, pc, sp, bp, is_memory_access,
- write_flag);
+ return (uptr)si->si_addr;
+}
+
+bool SignalContext::IsMemoryAccess() const {
+ auto si = static_cast<const siginfo_t *>(siginfo);
+ return si->si_signo == SIGSEGV;
}
int SignalContext::GetType() const {
diff --git a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
index d7fa5f645..7e89d0cc8 100644
--- a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
@@ -246,7 +246,7 @@ static void TracerThreadDieCallback() {
// Signal handler to wake up suspended threads when the tracer thread dies.
static void TracerThreadSignalHandler(int signum, void *siginfo, void *uctx) {
- SignalContext ctx = SignalContext::Create(siginfo, uctx);
+ SignalContext ctx(siginfo, uctx);
Printf("Tracer caught signal %d: addr=0x%zx pc=0x%zx sp=0x%zx\n", signum,
ctx.addr, ctx.pc, ctx.sp);
ThreadSuspender *inst = thread_suspender_instance;
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc
index 65e7aa8d7..ed7b68dd9 100644
--- a/lib/sanitizer_common/sanitizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_win.cc
@@ -915,33 +915,48 @@ bool IsAccessibleMemoryRange(uptr beg, uptr size) {
return true;
}
-SignalContext SignalContext::Create(void *siginfo, void *context) {
+void SignalContext::InitPcSpBp() {
EXCEPTION_RECORD *exception_record = (EXCEPTION_RECORD *)siginfo;
CONTEXT *context_record = (CONTEXT *)context;
- uptr pc = (uptr)exception_record->ExceptionAddress;
+ pc = (uptr)exception_record->ExceptionAddress;
#ifdef _WIN64
- uptr bp = (uptr)context_record->Rbp;
- uptr sp = (uptr)context_record->Rsp;
+ bp = (uptr)context_record->Rbp;
+ sp = (uptr)context_record->Rsp;
#else
- uptr bp = (uptr)context_record->Ebp;
- uptr sp = (uptr)context_record->Esp;
+ bp = (uptr)context_record->Ebp;
+ sp = (uptr)context_record->Esp;
#endif
- uptr access_addr = exception_record->ExceptionInformation[1];
+}
+
+uptr SignalContext::GetAddress() const {
+ EXCEPTION_RECORD *exception_record = (EXCEPTION_RECORD *)siginfo;
+ return exception_record->ExceptionInformation[1];
+}
+
+bool SignalContext::IsMemoryAccess() const {
+ return GetWriteFlag() != SignalContext::UNKNOWN;
+}
+int SignalContext::GetType() const {
+ return static_cast<const siginfo_t *>(siginfo)->si_signo;
+}
+
+SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
+ EXCEPTION_RECORD *exception_record = (EXCEPTION_RECORD *)siginfo;
// The contents of this array are documented at
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363082(v=vs.85).aspx
// The first element indicates read as 0, write as 1, or execute as 8. The
// second element is the faulting address.
- WriteFlag write_flag = SignalContext::UNKNOWN;
switch (exception_record->ExceptionInformation[0]) {
- case 0: write_flag = SignalContext::READ; break;
- case 1: write_flag = SignalContext::WRITE; break;
- case 8: write_flag = SignalContext::UNKNOWN; break;
+ case 0:
+ return SignalContext::READ;
+ case 1:
+ return SignalContext::WRITE;
+ case 8:
+ return SignalContext::UNKNOWN;
}
- bool is_memory_access = write_flag != SignalContext::UNKNOWN;
- return SignalContext(siginfo, context, access_addr, pc, sp, bp,
- is_memory_access, write_flag);
+ return SignalContext::UNKNOWN;
}
void SignalContext::DumpAllRegisters(void *context) {