Index: asan/asan_internal.h =================================================================== --- asan/asan_internal.h +++ asan/asan_internal.h @@ -62,6 +62,21 @@ class AsanThread; using __sanitizer::StackTrace; +// asan_posix.cc +struct SignalContext { + void *context; + uptr addr; + uptr pc; + uptr sp; + uptr bp; + + explicit SignalContext(void *context_, uptr addr_) { + internal_memset(this, 0, sizeof(SignalContext)); + context = context_; + addr = addr_; + } +}; + void AsanInitFromRtl(); // asan_rtl.cc @@ -75,7 +90,7 @@ void AsanCheckDynamicRTPrereqs(); void AsanCheckIncompatibleRT(); -void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp); +void GetPcSpBp(struct SignalContext *sig); void AsanOnSIGSEGV(int, void *siginfo, void *context); void MaybeReexec(); Index: asan/asan_linux.cc =================================================================== --- asan/asan_linux.cc +++ asan/asan_linux.cc @@ -148,73 +148,73 @@ } #endif // SANITIZER_ANDROID -void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { +void GetPcSpBp(struct SignalContext *sig) { #if defined(__arm__) - ucontext_t *ucontext = (ucontext_t*)context; - *pc = ucontext->uc_mcontext.arm_pc; - *bp = ucontext->uc_mcontext.arm_fp; - *sp = ucontext->uc_mcontext.arm_sp; + ucontext_t *ucontext = (ucontext_t*)sig->context; + sig->pc = ucontext->uc_mcontext.arm_pc; + sig->bp = ucontext->uc_mcontext.arm_fp; + sig->sp = ucontext->uc_mcontext.arm_sp; #elif defined(__aarch64__) - ucontext_t *ucontext = (ucontext_t*)context; - *pc = ucontext->uc_mcontext.pc; - *bp = ucontext->uc_mcontext.regs[29]; - *sp = ucontext->uc_mcontext.sp; + ucontext_t *ucontext = (ucontext_t*)sig->context; + sig->pc = ucontext->uc_mcontext.pc; + sig->bp = ucontext->uc_mcontext.regs[29]; + sig->sp = ucontext->uc_mcontext.sp; #elif defined(__hppa__) - ucontext_t *ucontext = (ucontext_t*)context; - *pc = ucontext->uc_mcontext.sc_iaoq[0]; + ucontext_t *ucontext = (ucontext_t*)sig->context; + sig->pc = ucontext->uc_mcontext.sc_iaoq[0]; /* GCC uses %r3 whenever a frame pointer is needed. */ - *bp = ucontext->uc_mcontext.sc_gr[3]; - *sp = ucontext->uc_mcontext.sc_gr[30]; + sig->bp = ucontext->uc_mcontext.sc_gr[3]; + sig->sp = ucontext->uc_mcontext.sc_gr[30]; #elif defined(__x86_64__) # if SANITIZER_FREEBSD - ucontext_t *ucontext = (ucontext_t*)context; - *pc = ucontext->uc_mcontext.mc_rip; - *bp = ucontext->uc_mcontext.mc_rbp; - *sp = ucontext->uc_mcontext.mc_rsp; + ucontext_t *ucontext = (ucontext_t*)sig->context; + sig->pc = ucontext->uc_mcontext.mc_rip; + sig->bp = ucontext->uc_mcontext.mc_rbp; + sig->sp = ucontext->uc_mcontext.mc_rsp; # else - ucontext_t *ucontext = (ucontext_t*)context; - *pc = ucontext->uc_mcontext.gregs[REG_RIP]; - *bp = ucontext->uc_mcontext.gregs[REG_RBP]; - *sp = ucontext->uc_mcontext.gregs[REG_RSP]; + ucontext_t *ucontext = (ucontext_t*)sig->context; + sig->pc = ucontext->uc_mcontext.gregs[REG_RIP]; + sig->bp = ucontext->uc_mcontext.gregs[REG_RBP]; + sig->sp = ucontext->uc_mcontext.gregs[REG_RSP]; # endif #elif defined(__i386__) # if SANITIZER_FREEBSD - ucontext_t *ucontext = (ucontext_t*)context; - *pc = ucontext->uc_mcontext.mc_eip; - *bp = ucontext->uc_mcontext.mc_ebp; - *sp = ucontext->uc_mcontext.mc_esp; + ucontext_t *ucontext = (ucontext_t*)sig->context; + sig->pc = ucontext->uc_mcontext.mc_eip; + sig->bp = ucontext->uc_mcontext.mc_ebp; + sig->sp = ucontext->uc_mcontext.mc_esp; # else - ucontext_t *ucontext = (ucontext_t*)context; - *pc = ucontext->uc_mcontext.gregs[REG_EIP]; - *bp = ucontext->uc_mcontext.gregs[REG_EBP]; - *sp = ucontext->uc_mcontext.gregs[REG_ESP]; + ucontext_t *ucontext = (ucontext_t*)sig->context; + sig->pc = ucontext->uc_mcontext.gregs[REG_EIP]; + sig->bp = ucontext->uc_mcontext.gregs[REG_EBP]; + sig->sp = ucontext->uc_mcontext.gregs[REG_ESP]; # endif #elif defined(__powerpc__) || defined(__powerpc64__) - ucontext_t *ucontext = (ucontext_t*)context; - *pc = ucontext->uc_mcontext.regs->nip; - *sp = ucontext->uc_mcontext.regs->gpr[PT_R1]; + ucontext_t *ucontext = (ucontext_t*)sig->context; + sig->pc = ucontext->uc_mcontext.regs->nip; + sig->sp = ucontext->uc_mcontext.regs->gpr[PT_R1]; // The powerpc{,64}-linux ABIs do not specify r31 as the frame // pointer, but GCC always uses r31 when we need a frame pointer. - *bp = ucontext->uc_mcontext.regs->gpr[PT_R31]; + sig->bp = ucontext->uc_mcontext.regs->gpr[PT_R31]; #elif defined(__sparc__) - ucontext_t *ucontext = (ucontext_t*)context; + ucontext_t *ucontext = (ucontext_t*)sig->context; uptr *stk_ptr; # if defined (__arch64__) - *pc = ucontext->uc_mcontext.mc_gregs[MC_PC]; - *sp = ucontext->uc_mcontext.mc_gregs[MC_O6]; - stk_ptr = (uptr *) (*sp + 2047); - *bp = stk_ptr[15]; + sig->pc = ucontext->uc_mcontext.mc_gregs[MC_PC]; + sig->sp = ucontext->uc_mcontext.mc_gregs[MC_O6]; + stk_ptr = (uptr *) (sig->sp + 2047); + sig->bp = stk_ptr[15]; # else - *pc = ucontext->uc_mcontext.gregs[REG_PC]; - *sp = ucontext->uc_mcontext.gregs[REG_O6]; - stk_ptr = (uptr *) *sp; - *bp = stk_ptr[15]; + sig->pc = ucontext->uc_mcontext.gregs[REG_PC]; + sig->sp = ucontext->uc_mcontext.gregs[REG_O6]; + stk_ptr = (uptr *) sig->sp; + sig->bp = stk_ptr[15]; # endif #elif defined(__mips__) - ucontext_t *ucontext = (ucontext_t*)context; - *pc = ucontext->uc_mcontext.gregs[31]; - *bp = ucontext->uc_mcontext.gregs[30]; - *sp = ucontext->uc_mcontext.gregs[29]; + ucontext_t *ucontext = (ucontext_t*)sig->context; + sig->pc = ucontext->uc_mcontext.gregs[31]; + sig->bp = ucontext->uc_mcontext.gregs[30]; + sig->sp = ucontext->uc_mcontext.gregs[29]; #else # error "Unsupported arch" #endif Index: asan/asan_mac.cc =================================================================== --- asan/asan_mac.cc +++ asan/asan_mac.cc @@ -40,20 +40,19 @@ namespace __asan { -void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { - ucontext_t *ucontext = (ucontext_t*)context; +void GetPcSpBp(struct SignalContext *sig) { + ucontext_t *ucontext = (ucontext_t*)sig->context; # if SANITIZER_WORDSIZE == 64 - *pc = ucontext->uc_mcontext->__ss.__rip; - *bp = ucontext->uc_mcontext->__ss.__rbp; - *sp = ucontext->uc_mcontext->__ss.__rsp; + sig->pc = ucontext->uc_mcontext->__ss.__rip; + sig->bp = ucontext->uc_mcontext->__ss.__rbp; + sig->sp = ucontext->uc_mcontext->__ss.__rsp; # else - *pc = ucontext->uc_mcontext->__ss.__eip; - *bp = ucontext->uc_mcontext->__ss.__ebp; - *sp = ucontext->uc_mcontext->__ss.__esp; + sig->pc = ucontext->uc_mcontext->__ss.__eip; + sig->bp = ucontext->uc_mcontext->__ss.__ebp; + sig->sp = ucontext->uc_mcontext->__ss.__esp; # endif // SANITIZER_WORDSIZE } - bool PlatformHasDifferentMemcpyAndMemmove() { // On OS X 10.7 memcpy() and memmove() are both resolved // into memmove$VARIANT$sse42. Index: asan/asan_posix.cc =================================================================== --- asan/asan_posix.cc +++ asan/asan_posix.cc @@ -37,8 +37,8 @@ int code = (int)((siginfo_t*)siginfo)->si_code; // Write the first message using the bullet-proof write. if (13 != internal_write(2, "ASAN:SIGSEGV\n", 13)) Die(); - uptr pc, sp, bp; - GetPcSpBp(context, &pc, &sp, &bp); + struct SignalContext sig(context, addr); + GetPcSpBp(&sig); // Access at a reasonable offset above SP, or slightly below it (to account // for x86_64 redzone, ARM push of multiple registers, etc) is probably a @@ -46,11 +46,11 @@ // We also check si_code to filter out SEGV caused by something else other // then hitting the guard page or unmapped memory, like, for example, // unaligned memory access. - if (addr + 128 > sp && addr < sp + 0xFFFF && + if (addr + 128 > sig.sp && addr < sig.sp + 0xFFFF && (code == si_SEGV_MAPERR || code == si_SEGV_ACCERR)) - ReportStackOverflow(pc, sp, bp, context, addr); + ReportStackOverflow(&sig); else - ReportSIGSEGV("SEGV", pc, sp, bp, context, addr); + ReportSIGSEGV("SEGV", &sig); } // ---------------------- TSD ---------------- {{{1 Index: asan/asan_report.h =================================================================== --- asan/asan_report.h +++ asan/asan_report.h @@ -52,10 +52,8 @@ void DescribeThread(AsanThreadContext *context); // Different kinds of error reports. -void NORETURN - ReportStackOverflow(uptr pc, uptr sp, uptr bp, void *context, uptr addr); -void NORETURN ReportSIGSEGV(const char *description, uptr pc, uptr sp, uptr bp, - void *context, uptr addr); +void NORETURN ReportStackOverflow(struct SignalContext *sig); +void NORETURN ReportSIGSEGV(const char *description, struct SignalContext *sig); void NORETURN ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size, BufferedStackTrace *free_stack); void NORETURN ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack); Index: asan/asan_report.cc =================================================================== --- asan/asan_report.cc +++ asan/asan_report.cc @@ -643,38 +643,37 @@ } }; -void ReportStackOverflow(uptr pc, uptr sp, uptr bp, void *context, uptr addr) { +void ReportStackOverflow(struct SignalContext *sig) { ScopedInErrorReport in_report; Decorator d; Printf("%s", d.Warning()); Report( "ERROR: AddressSanitizer: stack-overflow on address %p" " (pc %p bp %p sp %p T%d)\n", - (void *)addr, (void *)pc, (void *)bp, (void *)sp, + (void *)sig->addr, (void *)sig->pc, (void *)sig->bp, (void *)sig->sp, GetCurrentTidOrInvalid()); Printf("%s", d.EndWarning()); - GET_STACK_TRACE_SIGNAL(pc, bp, context); + GET_STACK_TRACE_SIGNAL(sig); stack.Print(); ReportErrorSummary("stack-overflow", &stack); } -void ReportSIGSEGV(const char *description, uptr pc, uptr sp, uptr bp, - void *context, uptr addr) { +void ReportSIGSEGV(const char *description, struct SignalContext *sig) { ScopedInErrorReport in_report; Decorator d; Printf("%s", d.Warning()); Report( "ERROR: AddressSanitizer: %s on unknown address %p" " (pc %p bp %p sp %p T%d)\n", - description, (void *)addr, (void *)pc, (void *)bp, (void *)sp, - GetCurrentTidOrInvalid()); - if (pc < GetPageSizeCached()) { + description, (void *)sig->addr, (void *)sig->pc, (void *)sig->bp, + (void *)sig->sp, GetCurrentTidOrInvalid()); + if (sig->pc < GetPageSizeCached()) { Report("Hint: pc points to the zero page.\n"); } Printf("%s", d.EndWarning()); - GET_STACK_TRACE_SIGNAL(pc, bp, context); + GET_STACK_TRACE_SIGNAL(sig); stack.Print(); - MaybeDumpInstructionBytes(pc); + MaybeDumpInstructionBytes(sig->pc); Printf("AddressSanitizer can not provide additional info.\n"); ReportErrorSummary("SEGV", &stack); } Index: asan/asan_stack.h =================================================================== --- asan/asan_stack.h +++ asan/asan_stack.h @@ -74,9 +74,10 @@ GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, 0, \ common_flags()->fast_unwind_on_fatal) -#define GET_STACK_TRACE_SIGNAL(pc, bp, context) \ +#define GET_STACK_TRACE_SIGNAL(sig) \ BufferedStackTrace stack; \ - GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context, \ + GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, \ + sig->pc, sig->bp, sig->context, \ common_flags()->fast_unwind_on_fatal) #define GET_STACK_TRACE_FATAL_HERE \ Index: asan/asan_win.cc =================================================================== --- asan/asan_win.cc +++ asan/asan_win.cc @@ -106,7 +106,11 @@ ? "access-violation" : "in-page-error"; uptr access_addr = exception_record->ExceptionInformation[1]; - ReportSIGSEGV(description, pc, sp, bp, context, access_addr); + struct SignalContext sig(context, access_addr); + sig.pc = pc; + sig.sp = sp; + sig.bp = bp; + ReportSIGSEGV(description, &sig); } // FIXME: Handle EXCEPTION_STACK_OVERFLOW here.