[RISCV][ASAN] implementation for previous/next pc routines for riscv64
authorIgor Chervatyuk <ichervatyuk@gmail.com>
Thu, 24 Sep 2020 07:23:45 +0000 (10:23 +0300)
committerapink <kupokupokupopo@gmail.com>
Thu, 1 Oct 2020 05:14:44 +0000 (08:14 +0300)
[7/11] patch series to port ASAN for riscv64

Depends On D87575

Reviewed By: eugenis, vitalybuka, luismarques

Differential Revision: https://reviews.llvm.org/D87577

compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp
compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h

index ef14fb7..ca2f90a 100644 (file)
@@ -21,6 +21,28 @@ uptr StackTrace::GetNextInstructionPc(uptr pc) {
   return pc + 8;
 #elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__)
   return pc + 4;
+#elif SANITIZER_RISCV64
+  // Current check order is 4 -> 2 -> 6 -> 8
+  u8 InsnByte = *(u8 *)(pc);
+  if (((InsnByte & 0x3) == 0x3) && ((InsnByte & 0x1c) != 0x1c)) {
+    // xxxxxxxxxxxbbb11 | 32 bit | bbb != 111
+    return pc + 4;
+  }
+  if ((InsnByte & 0x3) != 0x3) {
+    // xxxxxxxxxxxxxxaa | 16 bit | aa != 11
+    return pc + 2;
+  }
+  // RISC-V encoding allows instructions to be up to 8 bytes long
+  if ((InsnByte & 0x3f) == 0x1f) {
+    // xxxxxxxxxx011111 | 48 bit |
+    return pc + 6;
+  }
+  if ((InsnByte & 0x7f) == 0x3f) {
+    // xxxxxxxxx0111111 | 64 bit |
+    return pc + 8;
+  }
+  // bail-out if could not figure out the instruction size
+  return 0;
 #else
   return pc + 1;
 #endif
index 4162b58..9111acc 100644 (file)
@@ -85,6 +85,14 @@ uptr StackTrace::GetPreviousInstructionPc(uptr pc) {
   return pc - 4;
 #elif defined(__sparc__) || defined(__mips__)
   return pc - 8;
+#elif SANITIZER_RISCV64
+  // RV-64 has variable instruciton length...
+  // C extentions gives us 2-byte instructoins
+  // RV-64 has 4-byte instructions
+  // + RISCV architecture allows instructions up to 8 bytes
+  // It seems difficult to figure out the exact instruction length -
+  // pc - 2 seems like a safe option for the purposes of stack tracing
+  return pc - 2;
 #else
   return pc - 1;
 #endif