Add full support for initing registers.

- Fixes a few bugs in untested functionality.
- Add tests for the way the register handling code is used.
- Fix a few tests that were not reaping child processes.

Bug: 23762183

Test: Ran unit tests on host (32 bit and 64 bit).
Test: Ran unit tests on angler (32 bit and 64 bit).
Change-Id: I573d6617b4f1561f6e8494d7213c52086d112d97
diff --git a/libunwindstack/Regs.cpp b/libunwindstack/Regs.cpp
index da22b07..92b6e22 100644
--- a/libunwindstack/Regs.cpp
+++ b/libunwindstack/Regs.cpp
@@ -27,6 +27,7 @@
 #include "Machine.h"
 #include "MapInfo.h"
 #include "Regs.h"
+#include "Ucontext.h"
 #include "User.h"
 
 template <typename AddressType>
@@ -88,6 +89,11 @@
   return rel_pc - 4;
 }
 
+void RegsArm::SetFromRaw() {
+  set_pc(regs_[ARM_REG_PC]);
+  set_sp(regs_[ARM_REG_SP]);
+}
+
 RegsArm64::RegsArm64()
     : RegsImpl<uint64_t>(ARM64_REG_LAST, ARM64_REG_SP, Location(LOCATION_REGISTER, ARM64_REG_LR)) {}
 
@@ -102,6 +108,11 @@
   return rel_pc - 4;
 }
 
+void RegsArm64::SetFromRaw() {
+  set_pc(regs_[ARM64_REG_PC]);
+  set_sp(regs_[ARM64_REG_SP]);
+}
+
 RegsX86::RegsX86()
     : RegsImpl<uint32_t>(X86_REG_LAST, X86_REG_SP, Location(LOCATION_SP_OFFSET, -4)) {}
 
@@ -116,6 +127,11 @@
   return rel_pc - 1;
 }
 
+void RegsX86::SetFromRaw() {
+  set_pc(regs_[X86_REG_PC]);
+  set_sp(regs_[X86_REG_SP]);
+}
+
 RegsX86_64::RegsX86_64()
     : RegsImpl<uint64_t>(X86_64_REG_LAST, X86_64_REG_SP, Location(LOCATION_SP_OFFSET, -8)) {}
 
@@ -131,15 +147,17 @@
   return rel_pc - 1;
 }
 
+void RegsX86_64::SetFromRaw() {
+  set_pc(regs_[X86_64_REG_PC]);
+  set_sp(regs_[X86_64_REG_SP]);
+}
+
 static Regs* ReadArm(void* remote_data) {
   arm_user_regs* user = reinterpret_cast<arm_user_regs*>(remote_data);
 
   RegsArm* regs = new RegsArm();
   memcpy(regs->RawData(), &user->regs[0], ARM_REG_LAST * sizeof(uint32_t));
-
-  regs->set_pc(user->regs[ARM_REG_PC]);
-  regs->set_sp(user->regs[ARM_REG_SP]);
-
+  regs->SetFromRaw();
   return regs;
 }
 
@@ -148,9 +166,10 @@
 
   RegsArm64* regs = new RegsArm64();
   memcpy(regs->RawData(), &user->regs[0], (ARM64_REG_R31 + 1) * sizeof(uint64_t));
-  regs->set_pc(user->pc);
-  regs->set_sp(user->sp);
-
+  uint64_t* reg_data = reinterpret_cast<uint64_t*>(regs->RawData());
+  reg_data[ARM64_REG_PC] = user->pc;
+  reg_data[ARM64_REG_SP] = user->sp;
+  regs->SetFromRaw();
   return regs;
 }
 
@@ -168,9 +187,7 @@
   (*regs)[X86_REG_ESP] = user->esp;
   (*regs)[X86_REG_EIP] = user->eip;
 
-  regs->set_pc(user->eip);
-  regs->set_sp(user->esp);
-
+  regs->SetFromRaw();
   return regs;
 }
 
@@ -196,9 +213,7 @@
   (*regs)[X86_64_REG_RSP] = user->rsp;
   (*regs)[X86_64_REG_RIP] = user->rip;
 
-  regs->set_pc(user->rip);
-  regs->set_sp(user->rsp);
-
+  regs->SetFromRaw();
   return regs;
 }
 
@@ -231,3 +246,111 @@
   }
   return nullptr;
 }
+
+static Regs* CreateFromArmUcontext(void* ucontext) {
+  arm_ucontext_t* arm_ucontext = reinterpret_cast<arm_ucontext_t*>(ucontext);
+
+  RegsArm* regs = new RegsArm();
+  memcpy(regs->RawData(), &arm_ucontext->uc_mcontext.regs[0], ARM_REG_LAST * sizeof(uint32_t));
+  regs->SetFromRaw();
+  return regs;
+}
+
+static Regs* CreateFromArm64Ucontext(void* ucontext) {
+  arm64_ucontext_t* arm64_ucontext = reinterpret_cast<arm64_ucontext_t*>(ucontext);
+
+  RegsArm64* regs = new RegsArm64();
+  memcpy(regs->RawData(), &arm64_ucontext->uc_mcontext.regs[0], ARM64_REG_LAST * sizeof(uint64_t));
+  regs->SetFromRaw();
+  return regs;
+}
+
+static Regs* CreateFromX86Ucontext(void* ucontext) {
+  x86_ucontext_t* x86_ucontext = reinterpret_cast<x86_ucontext_t*>(ucontext);
+
+  RegsX86* regs = new RegsX86();
+  // Put the registers in the expected order.
+  (*regs)[X86_REG_GS] = x86_ucontext->uc_mcontext.gs;
+  (*regs)[X86_REG_FS] = x86_ucontext->uc_mcontext.fs;
+  (*regs)[X86_REG_ES] = x86_ucontext->uc_mcontext.es;
+  (*regs)[X86_REG_DS] = x86_ucontext->uc_mcontext.ds;
+  (*regs)[X86_REG_EDI] = x86_ucontext->uc_mcontext.edi;
+  (*regs)[X86_REG_ESI] = x86_ucontext->uc_mcontext.esi;
+  (*regs)[X86_REG_EBP] = x86_ucontext->uc_mcontext.ebp;
+  (*regs)[X86_REG_ESP] = x86_ucontext->uc_mcontext.esp;
+  (*regs)[X86_REG_EBX] = x86_ucontext->uc_mcontext.ebx;
+  (*regs)[X86_REG_EDX] = x86_ucontext->uc_mcontext.edx;
+  (*regs)[X86_REG_ECX] = x86_ucontext->uc_mcontext.ecx;
+  (*regs)[X86_REG_EAX] = x86_ucontext->uc_mcontext.eax;
+  (*regs)[X86_REG_EIP] = x86_ucontext->uc_mcontext.eip;
+  regs->SetFromRaw();
+  return regs;
+}
+
+static Regs* CreateFromX86_64Ucontext(void* ucontext) {
+  x86_64_ucontext_t* x86_64_ucontext = reinterpret_cast<x86_64_ucontext_t*>(ucontext);
+
+  RegsX86_64* regs = new RegsX86_64();
+  // Put the registers in the expected order.
+
+  // R8-R15
+  memcpy(&(*regs)[X86_64_REG_R8], &x86_64_ucontext->uc_mcontext.r8, 8 * sizeof(uint64_t));
+
+  // Rest of the registers.
+  (*regs)[X86_64_REG_RDI] = x86_64_ucontext->uc_mcontext.rdi;
+  (*regs)[X86_64_REG_RSI] = x86_64_ucontext->uc_mcontext.rsi;
+  (*regs)[X86_64_REG_RBP] = x86_64_ucontext->uc_mcontext.rbp;
+  (*regs)[X86_64_REG_RBX] = x86_64_ucontext->uc_mcontext.rbx;
+  (*regs)[X86_64_REG_RDX] = x86_64_ucontext->uc_mcontext.rdx;
+  (*regs)[X86_64_REG_RAX] = x86_64_ucontext->uc_mcontext.rax;
+  (*regs)[X86_64_REG_RCX] = x86_64_ucontext->uc_mcontext.rcx;
+  (*regs)[X86_64_REG_RSP] = x86_64_ucontext->uc_mcontext.rsp;
+  (*regs)[X86_64_REG_RIP] = x86_64_ucontext->uc_mcontext.rip;
+
+  regs->SetFromRaw();
+  return regs;
+}
+
+Regs* Regs::CreateFromUcontext(uint32_t machine_type, void* ucontext) {
+  switch (machine_type) {
+    case EM_386:
+      return CreateFromX86Ucontext(ucontext);
+    case EM_X86_64:
+      return CreateFromX86_64Ucontext(ucontext);
+    case EM_ARM:
+      return CreateFromArmUcontext(ucontext);
+    case EM_AARCH64:
+      return CreateFromArm64Ucontext(ucontext);
+  }
+  return nullptr;
+}
+
+uint32_t Regs::GetMachineType() {
+#if defined(__arm__)
+  return EM_ARM;
+#elif defined(__aarch64__)
+  return EM_AARCH64;
+#elif defined(__i386__)
+  return EM_386;
+#elif defined(__x86_64__)
+  return EM_X86_64;
+#else
+  abort();
+#endif
+}
+
+Regs* Regs::CreateFromLocal() {
+  Regs* regs;
+#if defined(__arm__)
+  regs = new RegsArm();
+#elif defined(__aarch64__)
+  regs = new RegsArm64();
+#elif defined(__i386__)
+  regs = new RegsX86();
+#elif defined(__x86_64__)
+  regs = new RegsX86_64();
+#else
+  abort();
+#endif
+  return regs;
+}