Index: asan/asan_internal.h =================================================================== --- asan/asan_internal.h +++ asan/asan_internal.h @@ -62,6 +62,19 @@ class AsanThread; using __sanitizer::StackTrace; +struct SignalContext { + void *context; + uptr addr; + uptr pc; + uptr sp; + uptr bp; + + SignalContext(void *context, uptr addr, + uptr pc = 0, uptr sp = 0, uptr bp = 0) : + context(context), addr(addr), pc(pc), sp(sp), bp(bp) { + } +}; + void AsanInitFromRtl(); // asan_rtl.cc @@ -75,7 +88,7 @@ void AsanCheckDynamicRTPrereqs(); void AsanCheckIncompatibleRT(); -void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp); +void GetPcSpBp(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(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(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 @@ -38,8 +38,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); + SignalContext sig(context, addr); + GetPcSpBp(&sig); // Access at a reasonable offset above SP, or slightly below it (to account // for x86_64 or PowerPC redzone, ARM push of multiple registers, etc) is @@ -47,11 +47,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 + 512 > sp && addr < sp + 0xFFFF && + if (addr + 512 > 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(const SignalContext &sig); +void NORETURN ReportSIGSEGV(const char *description, const 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(const 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, const 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 @@ -78,9 +78,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,8 @@ ? "access-violation" : "in-page-error"; uptr access_addr = exception_record->ExceptionInformation[1]; - ReportSIGSEGV(description, pc, sp, bp, context, access_addr); + SignalContext sig(context, access_addr, pc, sp, bp); + ReportSIGSEGV(description, sig); } // FIXME: Handle EXCEPTION_STACK_OVERFLOW here.