forked from OSchip/llvm-project
[mips] Implement GetWriteFlag() for mips
The read/write flag is set by manually decoding the instruction that caused the exception. It is implemented this way because the cause register which contains the needed flag was removed from the signal context structure which the user handler receives from the kernel. Patch by Milos Stojanovic. Differential Revision: https://reviews.llvm.org/D45768 llvm-svn: 330840
This commit is contained in:
parent
f3e043f67b
commit
1dd3584ec0
|
@ -1736,6 +1736,55 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
|
|||
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;
|
||||
|
|
|
@ -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.
|
|
@ -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.
|
Loading…
Reference in New Issue