diff options
Diffstat (limited to 'lib/sanitizer_common')
-rw-r--r-- | lib/sanitizer_common/sanitizer_common.h | 32 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux.cc | 6 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_mac.cc | 6 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_posix.cc | 15 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_win.cc | 43 |
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) { |