Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc @@ -1736,6 +1736,55 @@ uptr err = ucontext->uc_mcontext.gregs[REG_ERR]; #endif // SANITIZER_FREEBSD return err & PF_WRITE ? WRITE : READ; +#elif defined(__mips__) + uint32_t *exception_source; + uint32_t faulty_instruction; + uint32_t op_code; + + exception_source = (uint32_t *)ucontext->uc_mcontext.pc; + faulty_instruction = (uint32_t)(*exception_source); + + op_code = (faulty_instruction >> 26) & 0x3f; + + // FIXME: Add support for FPU, microMIPS, DSP, MSA memory instructions. + switch (op_code) { + case 0x28: // sb + case 0x29: // sh + case 0x2b: // sw + case 0x3f: // sd +#if __mips_isa_rev < 6 + case 0x2c: // sdl + case 0x2d: // sdr + case 0x2a: // swl + case 0x2e: // swr +#endif + return SignalContext::WRITE; + + case 0x20: // lb + case 0x24: // lbu + case 0x21: // lh + case 0x25: // lhu + case 0x23: // lw + case 0x27: // lwu + case 0x37: // ld +#if __mips_isa_rev < 6 + case 0x1a: // ldl + case 0x1b: // ldr + case 0x22: // lwl + case 0x26: // lwr +#endif + return SignalContext::READ; +#if __mips_isa_rev == 6 + case 0x3b: // pcrel + op_code = (faulty_instruction >> 19) & 0x3; + switch (op_code) { + case 0x1: // lwpc + case 0x2: // lwupc + return SignalContext::READ; + } +#endif + } + return SignalContext::UNKNOWN; #elif defined(__arm__) static const uptr FSR_WRITE = 1U << 11; uptr fsr = ucontext->uc_mcontext.error_code; Index: compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/illegal_read_test.cc =================================================================== --- compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/illegal_read_test.cc +++ compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/illegal_read_test.cc @@ -0,0 +1,14 @@ +// Test that there was an illegal READ memory access. +// RUN: %clangxx -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s + +// REQUIRES: stable-runtime + +volatile int *null = 0; +volatile int a; + +int main(int argc, char **argv) { + a = *null; + return 0; +} + +// CHECK: The signal is caused by a READ memory access. Index: compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/illegal_write_test.cc =================================================================== --- compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/illegal_write_test.cc +++ compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/illegal_write_test.cc @@ -0,0 +1,13 @@ +// Test that there was an illegal WRITE memory access. +// RUN: %clangxx -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s + +// REQUIRES: stable-runtime + +volatile int *null = 0; + +int main(int argc, char **argv) { + *null = 0; + return 0; +} + +// CHECK: The signal is caused by a WRITE memory access.