Merge "Cleanup the libbacktrace interface a bit."
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 5de0903..7f8e1e2 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -841,9 +841,15 @@
 
     // verify the signature on the table
     if (verify_verity_signature(verity) < 0) {
+        // Allow signature verification error when the device is unlocked
+        if (fs_mgr_is_device_unlocked()) {
+            retval = FS_MGR_SETUP_VERITY_SKIPPED;
+            LWARNING << "Allow signature verification error when the device is unlocked";
+            goto out;
+        }
         if (params.mode == VERITY_MODE_LOGGING) {
             // the user has been warned, allow mounting without dm-verity
-            retval = FS_MGR_SETUP_VERITY_SUCCESS;
+            retval = FS_MGR_SETUP_VERITY_SKIPPED;
             goto out;
         }
 
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 8196d58..d096b0d 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -323,11 +323,11 @@
     UmountStat stat = UmountPartitions(timeout - t.duration());
     if (stat != UMOUNT_STAT_SUCCESS) {
         LOG(INFO) << "umount timeout, last resort, kill all and try";
-        if (DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo(false);
+        if (DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo(true);
         KillAllProcesses();
         // even if it succeeds, still it is timeout and do not run fsck with all processes killed
-        UmountPartitions(0ms);
-        if (DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo(true);
+        UmountStat st = UmountPartitions(0ms);
+        if ((st != UMOUNT_STAT_SUCCESS) && DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo(false);
     }
 
     if (stat == UMOUNT_STAT_SUCCESS && runFsck) {
@@ -340,13 +340,6 @@
     return stat;
 }
 
-static void __attribute__((noreturn)) DoThermalOff() {
-    LOG(WARNING) << "Thermal system shutdown";
-    sync();
-    RebootSystem(ANDROID_RB_THERMOFF, "");
-    abort();
-}
-
 void DoReboot(unsigned int cmd, const std::string& reason, const std::string& rebootTarget,
               bool runFsck) {
     Timer t;
@@ -355,19 +348,25 @@
     android::base::WriteStringToFile(StringPrintf("%s\n", reason.c_str()), LAST_REBOOT_REASON_FILE,
                                      S_IRUSR | S_IWUSR, AID_SYSTEM, AID_SYSTEM);
 
-    if (cmd == ANDROID_RB_THERMOFF) {  // do not wait if it is thermal
-        DoThermalOff();
-        abort();
+    bool is_thermal_shutdown = false;
+    if (cmd == ANDROID_RB_THERMOFF) {
+        is_thermal_shutdown = true;
+        runFsck = false;
     }
 
-    auto shutdown_timeout = 0s;
+    auto shutdown_timeout = 0ms;
     if (!SHUTDOWN_ZERO_TIMEOUT) {
-        constexpr unsigned int shutdown_timeout_default = 6;
-        auto shutdown_timeout_property =
-            android::base::GetUintProperty("ro.build.shutdown_timeout", shutdown_timeout_default);
-        shutdown_timeout = std::chrono::seconds(shutdown_timeout_property);
+        if (is_thermal_shutdown) {
+            constexpr unsigned int thermal_shutdown_timeout = 1;
+            shutdown_timeout = std::chrono::seconds(thermal_shutdown_timeout);
+        } else {
+            constexpr unsigned int shutdown_timeout_default = 6;
+            auto shutdown_timeout_property = android::base::GetUintProperty(
+                "ro.build.shutdown_timeout", shutdown_timeout_default);
+            shutdown_timeout = std::chrono::seconds(shutdown_timeout_property);
+        }
     }
-    LOG(INFO) << "Shutdown timeout: " << shutdown_timeout.count() << " seconds";
+    LOG(INFO) << "Shutdown timeout: " << shutdown_timeout.count() << " ms";
 
     // keep debugging tools until non critical ones are all gone.
     const std::set<std::string> kill_after_apps{"tombstoned", "logd", "adbd"};
@@ -394,7 +393,7 @@
 
     // optional shutdown step
     // 1. terminate all services except shutdown critical ones. wait for delay to finish
-    if (shutdown_timeout > 0s) {
+    if (shutdown_timeout > 0ms) {
         LOG(INFO) << "terminating init services";
 
         // Ask all services to terminate except shutdown critical ones.
@@ -403,8 +402,8 @@
         });
 
         int service_count = 0;
-        // Up to half as long as shutdown_timeout or 3 seconds, whichever is lower.
-        auto termination_wait_timeout = std::min((shutdown_timeout + 1s) / 2, 3s);
+        // Only wait up to half of timeout here
+        auto termination_wait_timeout = shutdown_timeout / 2;
         while (t.duration() < termination_wait_timeout) {
             ServiceManager::GetInstance().ReapAnyOutstandingChildren();
 
@@ -456,7 +455,7 @@
     UmountStat stat = TryUmountAndFsck(runFsck, shutdown_timeout - t.duration());
     // Follow what linux shutdown is doing: one more sync with little bit delay
     sync();
-    std::this_thread::sleep_for(100ms);
+    if (!is_thermal_shutdown) std::this_thread::sleep_for(100ms);
     LogShutdownTime(stat, &t);
     // Reboot regardless of umount status. If umount fails, fsck after reboot will fix it.
     RebootSystem(cmd, rebootTarget);
diff --git a/init/ueventd_test.cpp b/init/ueventd_test.cpp
index 86d7055..4d9a1fa 100644
--- a/init/ueventd_test.cpp
+++ b/init/ueventd_test.cpp
@@ -63,7 +63,10 @@
 }
 
 TEST(ueventd, setegid_IsPerThread) {
-    if (getuid() != 0) return;
+    if (getuid() != 0) {
+        GTEST_LOG_(INFO) << "Skipping test, must be run as root.";
+        return;
+    }
 
     TemporaryDir dir;
 
@@ -78,13 +81,20 @@
 
     for (const auto& [file, expected_gid] : files_and_gids) {
         struct stat info;
-        EXPECT_EQ(0, stat(file.c_str(), &info));
+        ASSERT_EQ(0, stat(file.c_str(), &info));
         EXPECT_EQ(expected_gid, info.st_gid);
     }
 }
 
 TEST(ueventd, setfscreatecon_IsPerThread) {
-    if (getuid() != 0) return;
+    if (getuid() != 0) {
+        GTEST_LOG_(INFO) << "Skipping test, must be run as root.";
+        return;
+    }
+    if (!is_selinux_enabled() || security_getenforce() == 1) {
+        GTEST_LOG_(INFO) << "Skipping test, SELinux must be enabled and in permissive mode.";
+        return;
+    }
 
     const char* const contexts[] = {
         "u:object_r:audio_device:s0",
@@ -105,7 +115,7 @@
 
     for (const auto& [file, expected_context] : files_and_contexts) {
         char* file_context;
-        EXPECT_GT(getfilecon(file.c_str(), &file_context), 0);
+        ASSERT_GT(getfilecon(file.c_str(), &file_context), 0);
         EXPECT_EQ(expected_context, file_context);
         freecon(file_context);
     }
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index 94f0f8e..04c4cfa 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -115,6 +115,7 @@
         "tests/MemoryRangeTest.cpp",
         "tests/MemoryRemoteTest.cpp",
         "tests/MemoryTest.cpp",
+        "tests/RegsStepIfSignalHandlerTest.cpp",
         "tests/RegsTest.cpp",
         "tests/SymbolsTest.cpp",
         "tests/UnwindTest.cpp",
diff --git a/libunwindstack/Elf.cpp b/libunwindstack/Elf.cpp
index e962a73..4fc7c67 100644
--- a/libunwindstack/Elf.cpp
+++ b/libunwindstack/Elf.cpp
@@ -96,7 +96,7 @@
 }
 
 bool Elf::Step(uint64_t rel_pc, Regs* regs, Memory* process_memory) {
-  return valid_ && (regs->StepIfSignalHandler(process_memory) ||
+  return valid_ && (regs->StepIfSignalHandler(rel_pc, this, process_memory) ||
                     interface_->Step(rel_pc, regs, process_memory) ||
                     (gnu_debugdata_interface_ &&
                      gnu_debugdata_interface_->Step(rel_pc, regs, process_memory)));
diff --git a/libunwindstack/Regs.cpp b/libunwindstack/Regs.cpp
index 33319b1..dea7b87 100644
--- a/libunwindstack/Regs.cpp
+++ b/libunwindstack/Regs.cpp
@@ -350,9 +350,12 @@
   return regs;
 }
 
-bool RegsArm::StepIfSignalHandler(Memory* memory) {
+bool RegsArm::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) {
   uint32_t data;
-  if (!memory->Read(pc(), &data, sizeof(data))) {
+  Memory* elf_memory = elf->memory();
+  // Read from elf memory since it is usually more expensive to read from
+  // process memory.
+  if (!elf_memory->Read(rel_pc, &data, sizeof(data))) {
     return false;
   }
 
@@ -371,7 +374,7 @@
     // Form 3 (thumb):
     // 0x77 0x27              movs r7, #77
     // 0x00 0xdf              svc 0
-    if (!memory->Read(sp(), &data, sizeof(data))) {
+    if (!process_memory->Read(sp(), &data, sizeof(data))) {
       return false;
     }
     if (data == 0x5ac3c35a) {
@@ -395,7 +398,7 @@
     // Form 3 (thumb):
     // 0xad 0x27              movs r7, #ad
     // 0x00 0xdf              svc 0
-    if (!memory->Read(sp(), &data, sizeof(data))) {
+    if (!process_memory->Read(sp(), &data, sizeof(data))) {
       return false;
     }
     if (data == sp() + 8) {
@@ -410,16 +413,19 @@
     return false;
   }
 
-  if (!memory->Read(offset, regs_.data(), sizeof(uint32_t) * ARM_REG_LAST)) {
+  if (!process_memory->Read(offset, regs_.data(), sizeof(uint32_t) * ARM_REG_LAST)) {
     return false;
   }
   SetFromRaw();
   return true;
 }
 
-bool RegsArm64::StepIfSignalHandler(Memory* memory) {
+bool RegsArm64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) {
   uint64_t data;
-  if (!memory->Read(pc(), &data, sizeof(data))) {
+  Memory* elf_memory = elf->memory();
+  // Read from elf memory since it is usually more expensive to read from
+  // process memory.
+  if (!elf_memory->Read(rel_pc, &data, sizeof(data))) {
     return false;
   }
 
@@ -432,7 +438,8 @@
   }
 
   // SP + sizeof(siginfo_t) + uc_mcontext offset + X0 offset.
-  if (!memory->Read(sp() + 0x80 + 0xb0 + 0x08, regs_.data(), sizeof(uint64_t) * ARM64_REG_LAST)) {
+  if (!process_memory->Read(sp() + 0x80 + 0xb0 + 0x08, regs_.data(),
+                            sizeof(uint64_t) * ARM64_REG_LAST)) {
     return false;
   }
 
@@ -440,9 +447,12 @@
   return true;
 }
 
-bool RegsX86::StepIfSignalHandler(Memory* memory) {
+bool RegsX86::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) {
   uint64_t data;
-  if (!memory->Read(pc(), &data, sizeof(data))) {
+  Memory* elf_memory = elf->memory();
+  // Read from elf memory since it is usually more expensive to read from
+  // process memory.
+  if (!elf_memory->Read(rel_pc, &data, sizeof(data))) {
     return false;
   }
 
@@ -458,7 +468,7 @@
     //   int signum
     //   struct sigcontext (same format as mcontext)
     struct x86_mcontext_t context;
-    if (!memory->Read(sp() + 4, &context, sizeof(context))) {
+    if (!process_memory->Read(sp() + 4, &context, sizeof(context))) {
       return false;
     }
     regs_[X86_REG_EBP] = context.ebp;
@@ -484,12 +494,12 @@
 
     // Get the location of the sigcontext data.
     uint32_t ptr;
-    if (!memory->Read(sp() + 8, &ptr, sizeof(ptr))) {
+    if (!process_memory->Read(sp() + 8, &ptr, sizeof(ptr))) {
       return false;
     }
     // Only read the portion of the data structure we care about.
     x86_ucontext_t x86_ucontext;
-    if (!memory->Read(ptr + 0x14, &x86_ucontext.uc_mcontext, sizeof(x86_mcontext_t))) {
+    if (!process_memory->Read(ptr + 0x14, &x86_ucontext.uc_mcontext, sizeof(x86_mcontext_t))) {
       return false;
     }
     SetFromUcontext(&x86_ucontext);
@@ -498,14 +508,17 @@
   return false;
 }
 
-bool RegsX86_64::StepIfSignalHandler(Memory* memory) {
+bool RegsX86_64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) {
   uint64_t data;
-  if (!memory->Read(pc(), &data, sizeof(data)) || data != 0x0f0000000fc0c748) {
+  Memory* elf_memory = elf->memory();
+  // Read from elf memory since it is usually more expensive to read from
+  // process memory.
+  if (!elf_memory->Read(rel_pc, &data, sizeof(data)) || data != 0x0f0000000fc0c748) {
     return false;
   }
 
   uint16_t data2;
-  if (!memory->Read(pc() + 8, &data2, sizeof(data2)) || data2 != 0x0f05) {
+  if (!elf_memory->Read(rel_pc + 8, &data2, sizeof(data2)) || data2 != 0x0f05) {
     return false;
   }
 
@@ -517,7 +530,7 @@
   // Read the mcontext data from the stack.
   // sp points to the ucontext data structure, read only the mcontext part.
   x86_64_ucontext_t x86_64_ucontext;
-  if (!memory->Read(sp() + 0x28, &x86_64_ucontext.uc_mcontext, sizeof(x86_64_mcontext_t))) {
+  if (!process_memory->Read(sp() + 0x28, &x86_64_ucontext.uc_mcontext, sizeof(x86_64_mcontext_t))) {
     return false;
   }
   SetFromUcontext(&x86_64_ucontext);
diff --git a/libunwindstack/include/unwindstack/Regs.h b/libunwindstack/include/unwindstack/Regs.h
index 7623b7d..78e2c0d 100644
--- a/libunwindstack/include/unwindstack/Regs.h
+++ b/libunwindstack/include/unwindstack/Regs.h
@@ -57,7 +57,7 @@
 
   virtual uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) = 0;
 
-  virtual bool StepIfSignalHandler(Memory*) = 0;
+  virtual bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) = 0;
 
   virtual void SetFromRaw() = 0;
 
@@ -109,7 +109,7 @@
 
   void SetFromRaw() override;
 
-  bool StepIfSignalHandler(Memory* memory) override;
+  bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override;
 };
 
 class RegsArm64 : public RegsImpl<uint64_t> {
@@ -121,7 +121,7 @@
 
   void SetFromRaw() override;
 
-  bool StepIfSignalHandler(Memory* memory) override;
+  bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override;
 };
 
 class RegsX86 : public RegsImpl<uint32_t> {
@@ -133,7 +133,7 @@
 
   void SetFromRaw() override;
 
-  bool StepIfSignalHandler(Memory* memory) override;
+  bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override;
 
   void SetFromUcontext(x86_ucontext_t* ucontext);
 };
@@ -147,7 +147,7 @@
 
   void SetFromRaw() override;
 
-  bool StepIfSignalHandler(Memory* memory) override;
+  bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override;
 
   void SetFromUcontext(x86_64_ucontext_t* ucontext);
 };
diff --git a/libunwindstack/tests/RegsFake.h b/libunwindstack/tests/RegsFake.h
index f998da7..6669d7d 100644
--- a/libunwindstack/tests/RegsFake.h
+++ b/libunwindstack/tests/RegsFake.h
@@ -33,7 +33,7 @@
 
   uint64_t GetAdjustedPc(uint64_t, Elf*) override { return 0; }
   void SetFromRaw() override {}
-  bool StepIfSignalHandler(Memory*) override { return false; }
+  bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; }
   bool GetReturnAddressFromDefault(Memory*, uint64_t*) { return false; }
 };
 
diff --git a/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp b/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp
new file mode 100644
index 0000000..85192d5
--- /dev/null
+++ b/libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+
+#include <gtest/gtest.h>
+
+#include <unwindstack/Elf.h>
+#include <unwindstack/Regs.h>
+
+#include "Machine.h"
+
+#include "MemoryFake.h"
+
+namespace unwindstack {
+
+class RegsStepIfSignalHandlerTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    elf_memory_ = new MemoryFake;
+    elf_.reset(new Elf(elf_memory_));
+  }
+
+  void ArmStepIfSignalHandlerNonRt(uint32_t pc_data);
+  void ArmStepIfSignalHandlerRt(uint32_t pc_data);
+
+  MemoryFake* elf_memory_;
+  MemoryFake process_memory_;
+  std::unique_ptr<Elf> elf_;
+};
+
+void RegsStepIfSignalHandlerTest::ArmStepIfSignalHandlerNonRt(uint32_t pc_data) {
+  uint64_t addr = 0x1000;
+  RegsArm regs;
+  regs[ARM_REG_PC] = 0x5000;
+  regs[ARM_REG_SP] = addr;
+  regs.SetFromRaw();
+
+  elf_memory_->SetData32(0x5000, pc_data);
+
+  for (uint64_t index = 0; index <= 30; index++) {
+    process_memory_.SetData32(addr + index * 4, index * 0x10);
+  }
+
+  ASSERT_TRUE(regs.StepIfSignalHandler(0x5000, elf_.get(), &process_memory_));
+  EXPECT_EQ(0x100U, regs[ARM_REG_SP]);
+  EXPECT_EQ(0x120U, regs[ARM_REG_PC]);
+  EXPECT_EQ(0x100U, regs.sp());
+  EXPECT_EQ(0x120U, regs.pc());
+}
+
+TEST_F(RegsStepIfSignalHandlerTest, arm_step_if_signal_handler_non_rt) {
+  // Form 1
+  ArmStepIfSignalHandlerNonRt(0xe3a07077);
+
+  // Form 2
+  ArmStepIfSignalHandlerNonRt(0xef900077);
+
+  // Form 3
+  ArmStepIfSignalHandlerNonRt(0xdf002777);
+}
+
+void RegsStepIfSignalHandlerTest::ArmStepIfSignalHandlerRt(uint32_t pc_data) {
+  uint64_t addr = 0x1000;
+  RegsArm regs;
+  regs[ARM_REG_PC] = 0x5000;
+  regs[ARM_REG_SP] = addr;
+  regs.SetFromRaw();
+
+  elf_memory_->SetData32(0x5000, pc_data);
+
+  for (uint64_t index = 0; index <= 100; index++) {
+    process_memory_.SetData32(addr + index * 4, index * 0x10);
+  }
+
+  ASSERT_TRUE(regs.StepIfSignalHandler(0x5000, elf_.get(), &process_memory_));
+  EXPECT_EQ(0x350U, regs[ARM_REG_SP]);
+  EXPECT_EQ(0x370U, regs[ARM_REG_PC]);
+  EXPECT_EQ(0x350U, regs.sp());
+  EXPECT_EQ(0x370U, regs.pc());
+}
+
+TEST_F(RegsStepIfSignalHandlerTest, arm_step_if_signal_handler_rt) {
+  // Form 1
+  ArmStepIfSignalHandlerRt(0xe3a070ad);
+
+  // Form 2
+  ArmStepIfSignalHandlerRt(0xef9000ad);
+
+  // Form 3
+  ArmStepIfSignalHandlerRt(0xdf0027ad);
+}
+
+TEST_F(RegsStepIfSignalHandlerTest, arm64_step_if_signal_handler) {
+  uint64_t addr = 0x1000;
+  RegsArm64 regs;
+  regs[ARM64_REG_PC] = 0x8000;
+  regs[ARM64_REG_SP] = addr;
+  regs.SetFromRaw();
+
+  elf_memory_->SetData64(0x8000, 0xd4000001d2801168ULL);
+
+  for (uint64_t index = 0; index <= 100; index++) {
+    process_memory_.SetData64(addr + index * 8, index * 0x10);
+  }
+
+  ASSERT_TRUE(regs.StepIfSignalHandler(0x8000, elf_.get(), &process_memory_));
+  EXPECT_EQ(0x460U, regs[ARM64_REG_SP]);
+  EXPECT_EQ(0x470U, regs[ARM64_REG_PC]);
+  EXPECT_EQ(0x460U, regs.sp());
+  EXPECT_EQ(0x470U, regs.pc());
+}
+
+TEST_F(RegsStepIfSignalHandlerTest, x86_step_if_signal_handler_no_siginfo) {
+  uint64_t addr = 0xa00;
+  RegsX86 regs;
+  regs[X86_REG_EIP] = 0x4100;
+  regs[X86_REG_ESP] = addr;
+  regs.SetFromRaw();
+
+  elf_memory_->SetData64(0x4100, 0x80cd00000077b858ULL);
+  for (uint64_t index = 0; index <= 25; index++) {
+    process_memory_.SetData32(addr + index * 4, index * 0x10);
+  }
+
+  ASSERT_TRUE(regs.StepIfSignalHandler(0x4100, elf_.get(), &process_memory_));
+  EXPECT_EQ(0x70U, regs[X86_REG_EBP]);
+  EXPECT_EQ(0x80U, regs[X86_REG_ESP]);
+  EXPECT_EQ(0x90U, regs[X86_REG_EBX]);
+  EXPECT_EQ(0xa0U, regs[X86_REG_EDX]);
+  EXPECT_EQ(0xb0U, regs[X86_REG_ECX]);
+  EXPECT_EQ(0xc0U, regs[X86_REG_EAX]);
+  EXPECT_EQ(0xf0U, regs[X86_REG_EIP]);
+  EXPECT_EQ(0x80U, regs.sp());
+  EXPECT_EQ(0xf0U, regs.pc());
+}
+
+TEST_F(RegsStepIfSignalHandlerTest, x86_step_if_signal_handler_siginfo) {
+  uint64_t addr = 0xa00;
+  RegsX86 regs;
+  regs[X86_REG_EIP] = 0x4100;
+  regs[X86_REG_ESP] = addr;
+  regs.SetFromRaw();
+
+  elf_memory_->SetData64(0x4100, 0x0080cd000000adb8ULL);
+  addr += 8;
+  // Pointer to ucontext data.
+  process_memory_.SetData32(addr, 0x8100);
+
+  addr = 0x8100;
+  for (uint64_t index = 0; index <= 30; index++) {
+    process_memory_.SetData32(addr + index * 4, index * 0x10);
+  }
+
+  ASSERT_TRUE(regs.StepIfSignalHandler(0x4100, elf_.get(), &process_memory_));
+  EXPECT_EQ(0xb0U, regs[X86_REG_EBP]);
+  EXPECT_EQ(0xc0U, regs[X86_REG_ESP]);
+  EXPECT_EQ(0xd0U, regs[X86_REG_EBX]);
+  EXPECT_EQ(0xe0U, regs[X86_REG_EDX]);
+  EXPECT_EQ(0xf0U, regs[X86_REG_ECX]);
+  EXPECT_EQ(0x100U, regs[X86_REG_EAX]);
+  EXPECT_EQ(0x130U, regs[X86_REG_EIP]);
+  EXPECT_EQ(0xc0U, regs.sp());
+  EXPECT_EQ(0x130U, regs.pc());
+}
+
+TEST_F(RegsStepIfSignalHandlerTest, x86_64_step_if_signal_handler) {
+  uint64_t addr = 0x500;
+  RegsX86_64 regs;
+  regs[X86_64_REG_RIP] = 0x7000;
+  regs[X86_64_REG_RSP] = addr;
+  regs.SetFromRaw();
+
+  elf_memory_->SetData64(0x7000, 0x0f0000000fc0c748);
+  elf_memory_->SetData16(0x7008, 0x0f05);
+
+  for (uint64_t index = 0; index <= 30; index++) {
+    process_memory_.SetData64(addr + index * 8, index * 0x10);
+  }
+
+  ASSERT_TRUE(regs.StepIfSignalHandler(0x7000, elf_.get(), &process_memory_));
+  EXPECT_EQ(0x140U, regs[X86_64_REG_RSP]);
+  EXPECT_EQ(0x150U, regs[X86_64_REG_RIP]);
+  EXPECT_EQ(0x140U, regs.sp());
+  EXPECT_EQ(0x150U, regs.pc());
+}
+
+}  // namespace unwindstack
diff --git a/libunwindstack/tests/RegsTest.cpp b/libunwindstack/tests/RegsTest.cpp
index 9622166..e6de56a 100644
--- a/libunwindstack/tests/RegsTest.cpp
+++ b/libunwindstack/tests/RegsTest.cpp
@@ -23,8 +23,6 @@
 #include <unwindstack/MapInfo.h>
 #include <unwindstack/Regs.h>
 
-#include "Machine.h"
-
 #include "MemoryFake.h"
 
 namespace unwindstack {
@@ -62,7 +60,7 @@
 
   uint64_t GetAdjustedPc(uint64_t, Elf*) override { return 0; }
   void SetFromRaw() override {}
-  bool StepIfSignalHandler(Memory*) override { return false; }
+  bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; }
 };
 
 class RegsTest : public ::testing::Test {
@@ -77,9 +75,6 @@
   template <typename AddressType>
   void RegsReturnAddressRegister();
 
-  void ArmStepIfSignalHandlerNonRt(uint32_t pc_data);
-  void ArmStepIfSignalHandlerRt(uint32_t pc_data);
-
   ElfInterfaceFake* elf_interface_;
   MemoryFake* memory_;
   std::unique_ptr<ElfFake> elf_;
@@ -291,160 +286,4 @@
   EXPECT_EQ(0x4900000000U, x86_64.pc());
 }
 
-void RegsTest::ArmStepIfSignalHandlerNonRt(uint32_t pc_data) {
-  uint64_t addr = 0x1000;
-  RegsArm regs;
-  regs[ARM_REG_PC] = 0x5000;
-  regs[ARM_REG_SP] = addr;
-  regs.SetFromRaw();
-
-  memory_->SetData32(0x5000, pc_data);
-
-  for (uint64_t index = 0; index <= 30; index++) {
-    memory_->SetData32(addr + index * 4, index * 0x10);
-  }
-
-  ASSERT_TRUE(regs.StepIfSignalHandler(memory_));
-  EXPECT_EQ(0x100U, regs[ARM_REG_SP]);
-  EXPECT_EQ(0x120U, regs[ARM_REG_PC]);
-  EXPECT_EQ(0x100U, regs.sp());
-  EXPECT_EQ(0x120U, regs.pc());
-}
-
-TEST_F(RegsTest, arm_step_if_signal_handler_non_rt) {
-  // Form 1
-  ArmStepIfSignalHandlerNonRt(0xe3a07077);
-
-  // Form 2
-  ArmStepIfSignalHandlerNonRt(0xef900077);
-
-  // Form 3
-  ArmStepIfSignalHandlerNonRt(0xdf002777);
-}
-
-void RegsTest::ArmStepIfSignalHandlerRt(uint32_t pc_data) {
-  uint64_t addr = 0x1000;
-  RegsArm regs;
-  regs[ARM_REG_PC] = 0x5000;
-  regs[ARM_REG_SP] = addr;
-  regs.SetFromRaw();
-
-  memory_->SetData32(0x5000, pc_data);
-
-  for (uint64_t index = 0; index <= 100; index++) {
-    memory_->SetData32(addr + index * 4, index * 0x10);
-  }
-
-  ASSERT_TRUE(regs.StepIfSignalHandler(memory_));
-  EXPECT_EQ(0x350U, regs[ARM_REG_SP]);
-  EXPECT_EQ(0x370U, regs[ARM_REG_PC]);
-  EXPECT_EQ(0x350U, regs.sp());
-  EXPECT_EQ(0x370U, regs.pc());
-}
-
-TEST_F(RegsTest, arm_step_if_signal_handler_rt) {
-  // Form 1
-  ArmStepIfSignalHandlerRt(0xe3a070ad);
-
-  // Form 2
-  ArmStepIfSignalHandlerRt(0xef9000ad);
-
-  // Form 3
-  ArmStepIfSignalHandlerRt(0xdf0027ad);
-}
-
-TEST_F(RegsTest, arm64_step_if_signal_handler) {
-  uint64_t addr = 0x1000;
-  RegsArm64 regs;
-  regs[ARM64_REG_PC] = 0x8000;
-  regs[ARM64_REG_SP] = addr;
-  regs.SetFromRaw();
-
-  memory_->SetData64(0x8000, 0xd4000001d2801168ULL);
-
-  for (uint64_t index = 0; index <= 100; index++) {
-    memory_->SetData64(addr + index * 8, index * 0x10);
-  }
-
-  ASSERT_TRUE(regs.StepIfSignalHandler(memory_));
-  EXPECT_EQ(0x460U, regs[ARM64_REG_SP]);
-  EXPECT_EQ(0x470U, regs[ARM64_REG_PC]);
-  EXPECT_EQ(0x460U, regs.sp());
-  EXPECT_EQ(0x470U, regs.pc());
-}
-
-TEST_F(RegsTest, x86_step_if_signal_handler_no_siginfo) {
-  uint64_t addr = 0xa00;
-  RegsX86 regs;
-  regs[X86_REG_EIP] = 0x4100;
-  regs[X86_REG_ESP] = addr;
-  regs.SetFromRaw();
-
-  memory_->SetData64(0x4100, 0x80cd00000077b858ULL);
-  for (uint64_t index = 0; index <= 25; index++) {
-    memory_->SetData32(addr + index * 4, index * 0x10);
-  }
-
-  ASSERT_TRUE(regs.StepIfSignalHandler(memory_));
-  EXPECT_EQ(0x70U, regs[X86_REG_EBP]);
-  EXPECT_EQ(0x80U, regs[X86_REG_ESP]);
-  EXPECT_EQ(0x90U, regs[X86_REG_EBX]);
-  EXPECT_EQ(0xa0U, regs[X86_REG_EDX]);
-  EXPECT_EQ(0xb0U, regs[X86_REG_ECX]);
-  EXPECT_EQ(0xc0U, regs[X86_REG_EAX]);
-  EXPECT_EQ(0xf0U, regs[X86_REG_EIP]);
-  EXPECT_EQ(0x80U, regs.sp());
-  EXPECT_EQ(0xf0U, regs.pc());
-}
-
-TEST_F(RegsTest, x86_step_if_signal_handler_siginfo) {
-  uint64_t addr = 0xa00;
-  RegsX86 regs;
-  regs[X86_REG_EIP] = 0x4100;
-  regs[X86_REG_ESP] = addr;
-  regs.SetFromRaw();
-
-  memory_->SetData64(0x4100, 0x0080cd000000adb8ULL);
-  addr += 8;
-  // Pointer to ucontext data.
-  memory_->SetData32(addr, 0x8100);
-
-  addr = 0x8100;
-  for (uint64_t index = 0; index <= 30; index++) {
-    memory_->SetData32(addr + index * 4, index * 0x10);
-  }
-
-  ASSERT_TRUE(regs.StepIfSignalHandler(memory_));
-  EXPECT_EQ(0xb0U, regs[X86_REG_EBP]);
-  EXPECT_EQ(0xc0U, regs[X86_REG_ESP]);
-  EXPECT_EQ(0xd0U, regs[X86_REG_EBX]);
-  EXPECT_EQ(0xe0U, regs[X86_REG_EDX]);
-  EXPECT_EQ(0xf0U, regs[X86_REG_ECX]);
-  EXPECT_EQ(0x100U, regs[X86_REG_EAX]);
-  EXPECT_EQ(0x130U, regs[X86_REG_EIP]);
-  EXPECT_EQ(0xc0U, regs.sp());
-  EXPECT_EQ(0x130U, regs.pc());
-}
-
-TEST_F(RegsTest, x86_64_step_if_signal_handler) {
-  uint64_t addr = 0x500;
-  RegsX86_64 regs;
-  regs[X86_64_REG_RIP] = 0x7000;
-  regs[X86_64_REG_RSP] = addr;
-  regs.SetFromRaw();
-
-  memory_->SetData64(0x7000, 0x0f0000000fc0c748);
-  memory_->SetData16(0x7008, 0x0f05);
-
-  for (uint64_t index = 0; index <= 30; index++) {
-    memory_->SetData64(addr + index * 8, index * 0x10);
-  }
-
-  ASSERT_TRUE(regs.StepIfSignalHandler(memory_));
-  EXPECT_EQ(0x140U, regs[X86_64_REG_RSP]);
-  EXPECT_EQ(0x150U, regs[X86_64_REG_RIP]);
-  EXPECT_EQ(0x140U, regs.sp());
-  EXPECT_EQ(0x150U, regs.pc());
-}
-
 }  // namespace unwindstack