riscv64: implement tests 004-SignalTest and 115-native-bridge.

Also, make the tests fail on unsupported architectures (instead of being
ignored and marked as passed).

Bug: 271573990
Test: run ART test 004-SignalTest and 115-native-bridge on a Linux
  RISC-V VM (note that 115-native-bridge is skipped on target):

  lunch aosp_riscv64-userdebug

  export ART_TEST_SSH_USER=ubuntu
  export ART_TEST_SSH_HOST=localhost
  export ART_TEST_SSH_PORT=10001
  export ART_TEST_ON_VM=true

  . art/tools/buildbot-utils.sh
  art/tools/buildbot-build.sh --target

  # Create, boot and configure the VM.
  art/tools/buildbot-vm.sh create
  art/tools/buildbot-vm.sh boot
  art/tools/buildbot-vm.sh setup-ssh  # password: 'ubuntu'

  art/tools/buildbot-cleanup-device.sh
  art/tools/buildbot-setup-device.sh
  art/tools/buildbot-sync.sh

  art/test.py --target -r --no-prebuild --ndebug --64 --interpreter \
    004-SignalTest 115-native-bridge

Change-Id: I31c22f0acf2ecc84752f315b304fb6a51c1b3bea
diff --git a/test/004-SignalTest/signaltest.cc b/test/004-SignalTest/signaltest.cc
index daa31d3..18b4502 100644
--- a/test/004-SignalTest/signaltest.cc
+++ b/test/004-SignalTest/signaltest.cc
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <android-base/logging.h>
+
 #include <jni.h>
 #include <signal.h>
 #include <stdio.h>
@@ -79,11 +81,15 @@
 #if defined(__arm__)
   ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
   mcontext_t* mc = reinterpret_cast<mcontext_t*>(&uc->uc_mcontext);
-  mc->arm_pc += 2;          // Skip instruction causing segv.
+  mc->arm_pc += 2;  // Skip instruction causing segv.
 #elif defined(__aarch64__)
   ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
   mcontext_t* mc = reinterpret_cast<mcontext_t*>(&uc->uc_mcontext);
-  mc->pc += 4;          // Skip instruction causing segv.
+  mc->pc += 4;  // Skip instruction causing segv.
+#elif defined(__riscv)
+  ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
+  mcontext_t* mc = reinterpret_cast<mcontext_t*>(&uc->uc_mcontext);
+  mc->__gregs[REG_PC] += 4;  // Skip instruction causing segv.
 #elif defined(__i386__)
   ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
   uc->CTX_EIP += 3;
@@ -92,6 +98,7 @@
   uc->CTX_EIP += 2;
 #else
   UNUSED(context);
+  UNIMPLEMENTED(FATAL) << "Unsupported architecture";
 #endif
 
   printf("signal handler done\n");
@@ -157,6 +164,10 @@
 #if defined(__arm__) || defined(__i386__) || defined(__aarch64__)
   // On supported architectures we cause a real SEGV.
   *go_away_compiler = 'a';
+#elif defined(__riscv)
+  // Cause a SEGV using an instruction known to be 4 bytes long to account for hardcoded jump
+  // in the signal handler
+  asm volatile("ld zero, (zero);" : : :);
 #elif defined(__x86_64__)
   // Cause a SEGV using an instruction known to be 2 bytes long to account for hardcoded jump
   // in the signal handler
diff --git a/test/115-native-bridge/nativebridge.cc b/test/115-native-bridge/nativebridge.cc
index a5541ce..4388747 100644
--- a/test/115-native-bridge/nativebridge.cc
+++ b/test/115-native-bridge/nativebridge.cc
@@ -195,6 +195,10 @@
 static void raise_sigsegv() {
 #if defined(__arm__) || defined(__i386__) || defined(__aarch64__)
   *go_away_compiler = 'a';
+#elif defined(__riscv)
+  // Cause a SEGV using an instruction known to be 4 bytes long to account for hardcoded jump
+  // in the signal handler
+  asm volatile("ld zero, (zero);" : : :);
 #elif defined(__x86_64__)
   // Cause a SEGV using an instruction known to be 2 bytes long to account for hardcoded jump
   // in the signal handler
@@ -553,17 +557,20 @@
 #endif
 #endif
 
-static bool StandardSignalHandler(int sig, siginfo_t* info ATTRIBUTE_UNUSED,
-                                     void* context) {
+static bool StandardSignalHandler(int sig, siginfo_t* info ATTRIBUTE_UNUSED, void* context) {
   if (sig == SIGSEGV) {
 #if defined(__arm__)
     ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
     mcontext_t* mc = reinterpret_cast<mcontext_t*>(&uc->uc_mcontext);
-    mc->arm_pc += 2;          // Skip instruction causing segv & sigill.
+    mc->arm_pc += 2;  // Skip instruction causing segv & sigill.
 #elif defined(__aarch64__)
     ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
     mcontext_t* mc = reinterpret_cast<mcontext_t*>(&uc->uc_mcontext);
-    mc->pc += 4;          // Skip instruction causing segv & sigill.
+    mc->pc += 4;  // Skip instruction causing segv & sigill.
+#elif defined(__riscv)
+    ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
+    mcontext_t* mc = reinterpret_cast<mcontext_t*>(&uc->uc_mcontext);
+    mc->__gregs[REG_PC] += 4;  // Skip instruction causing segv & sigill.
 #elif defined(__i386__)
     ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
     uc->CTX_EIP += 3;
@@ -572,6 +579,7 @@
     uc->CTX_EIP += 2;
 #else
     UNUSED(context);
+    UNIMPLEMENTED(FATAL) << "Unsupported architecture";
 #endif
   }