libunwindstack: make machine type a property of Regs.

There are no actual users of the machine type output parameter to
Regs::RemoteGet. The concrete implementations of Regs know what machine
type they represent anyway, so provide an accessor to query.

Test: treehugger
Test: libunwindstack tests on 32/64-bit host, hikey960
Change-Id: Ia25910531d36c41b2b6919f154cfa914aae63117
diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp
index e79bca3..3b2f38e 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -160,7 +160,8 @@
     // one extra function call appearing in the unwind.
     unwindstack::RegsGetLocal(regs.get());
   } else {
-    regs.reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::GetMachineType(), ucontext));
+    regs.reset(
+        unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentMachineType(), ucontext));
   }
 
   error_ = BACKTRACE_UNWIND_NO_ERROR;
@@ -177,10 +178,10 @@
 bool UnwindStackPtrace::Unwind(size_t num_ignore_frames, ucontext_t* context) {
   std::unique_ptr<unwindstack::Regs> regs;
   if (context == nullptr) {
-    uint32_t machine_type;
-    regs.reset(unwindstack::Regs::RemoteGet(Tid(), &machine_type));
+    regs.reset(unwindstack::Regs::RemoteGet(Tid()));
   } else {
-    regs.reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::GetMachineType(), context));
+    regs.reset(
+        unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentMachineType(), context));
   }
 
   error_ = BACKTRACE_UNWIND_NO_ERROR;
diff --git a/libunwindstack/Regs.cpp b/libunwindstack/Regs.cpp
index dea7b87..4d09c1b 100644
--- a/libunwindstack/Regs.cpp
+++ b/libunwindstack/Regs.cpp
@@ -56,6 +56,10 @@
 RegsArm::RegsArm()
     : RegsImpl<uint32_t>(ARM_REG_LAST, ARM_REG_SP, Location(LOCATION_REGISTER, ARM_REG_LR)) {}
 
+uint32_t RegsArm::MachineType() {
+  return EM_ARM;
+}
+
 uint64_t RegsArm::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
   if (!elf->valid()) {
     return rel_pc;
@@ -90,6 +94,10 @@
 RegsArm64::RegsArm64()
     : RegsImpl<uint64_t>(ARM64_REG_LAST, ARM64_REG_SP, Location(LOCATION_REGISTER, ARM64_REG_LR)) {}
 
+uint32_t RegsArm64::MachineType() {
+  return EM_AARCH64;
+}
+
 uint64_t RegsArm64::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
   if (!elf->valid()) {
     return rel_pc;
@@ -109,6 +117,10 @@
 RegsX86::RegsX86()
     : RegsImpl<uint32_t>(X86_REG_LAST, X86_REG_SP, Location(LOCATION_SP_OFFSET, -4)) {}
 
+uint32_t RegsX86::MachineType() {
+  return EM_386;
+}
+
 uint64_t RegsX86::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
   if (!elf->valid()) {
     return rel_pc;
@@ -128,6 +140,10 @@
 RegsX86_64::RegsX86_64()
     : RegsImpl<uint64_t>(X86_64_REG_LAST, X86_64_REG_SP, Location(LOCATION_SP_OFFSET, -8)) {}
 
+uint32_t RegsX86_64::MachineType() {
+  return EM_X86_64;
+}
+
 uint64_t RegsX86_64::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
   if (!elf->valid()) {
     return rel_pc;
@@ -212,7 +228,7 @@
 
 // This function assumes that reg_data is already aligned to a 64 bit value.
 // If not this could crash with an unaligned access.
-Regs* Regs::RemoteGet(pid_t pid, uint32_t* machine_type) {
+Regs* Regs::RemoteGet(pid_t pid) {
   // Make the buffer large enough to contain the largest registers type.
   std::vector<uint64_t> buffer(MAX_USER_REGS_SIZE / sizeof(uint64_t));
   struct iovec io;
@@ -225,16 +241,12 @@
 
   switch (io.iov_len) {
   case sizeof(x86_user_regs):
-    *machine_type = EM_386;
     return ReadX86(buffer.data());
   case sizeof(x86_64_user_regs):
-    *machine_type = EM_X86_64;
     return ReadX86_64(buffer.data());
   case sizeof(arm_user_regs):
-    *machine_type = EM_ARM;
     return ReadArm(buffer.data());
   case sizeof(arm64_user_regs):
-    *machine_type = EM_AARCH64;
     return ReadArm64(buffer.data());
   }
   return nullptr;
@@ -320,7 +332,7 @@
   return nullptr;
 }
 
-uint32_t Regs::GetMachineType() {
+uint32_t Regs::CurrentMachineType() {
 #if defined(__arm__)
   return EM_ARM;
 #elif defined(__aarch64__)
diff --git a/libunwindstack/include/unwindstack/Regs.h b/libunwindstack/include/unwindstack/Regs.h
index 78e2c0d..ed4d38a 100644
--- a/libunwindstack/include/unwindstack/Regs.h
+++ b/libunwindstack/include/unwindstack/Regs.h
@@ -49,6 +49,8 @@
       : total_regs_(total_regs), sp_reg_(sp_reg), return_loc_(return_loc) {}
   virtual ~Regs() = default;
 
+  virtual uint32_t MachineType() = 0;
+
   virtual void* RawData() = 0;
   virtual uint64_t pc() = 0;
   virtual uint64_t sp() = 0;
@@ -64,8 +66,8 @@
   uint16_t sp_reg() { return sp_reg_; }
   uint16_t total_regs() { return total_regs_; }
 
-  static uint32_t GetMachineType();
-  static Regs* RemoteGet(pid_t pid, uint32_t* machine_type);
+  static uint32_t CurrentMachineType();
+  static Regs* RemoteGet(pid_t pid);
   static Regs* CreateFromUcontext(uint32_t machine_type, void* ucontext);
   static Regs* CreateFromLocal();
 
@@ -105,6 +107,8 @@
   RegsArm();
   virtual ~RegsArm() = default;
 
+  virtual uint32_t MachineType() override final;
+
   uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
 
   void SetFromRaw() override;
@@ -117,6 +121,8 @@
   RegsArm64();
   virtual ~RegsArm64() = default;
 
+  virtual uint32_t MachineType() override final;
+
   uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
 
   void SetFromRaw() override;
@@ -129,6 +135,8 @@
   RegsX86();
   virtual ~RegsX86() = default;
 
+  virtual uint32_t MachineType() override final;
+
   uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
 
   void SetFromRaw() override;
@@ -143,6 +151,8 @@
   RegsX86_64();
   virtual ~RegsX86_64() = default;
 
+  virtual uint32_t MachineType() override final;
+
   uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
 
   void SetFromRaw() override;
diff --git a/libunwindstack/tests/RegsFake.h b/libunwindstack/tests/RegsFake.h
index 6669d7d..c76ecaa 100644
--- a/libunwindstack/tests/RegsFake.h
+++ b/libunwindstack/tests/RegsFake.h
@@ -31,6 +31,8 @@
       : RegsImpl<TypeParam>(total_regs, sp_reg, Regs::Location(Regs::LOCATION_UNKNOWN, 0)) {}
   virtual ~RegsFake() = default;
 
+  uint32_t MachineType() override { return 0; }
+
   uint64_t GetAdjustedPc(uint64_t, Elf*) override { return 0; }
   void SetFromRaw() override {}
   bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; }
diff --git a/libunwindstack/tests/RegsTest.cpp b/libunwindstack/tests/RegsTest.cpp
index e6de56a..f549a50 100644
--- a/libunwindstack/tests/RegsTest.cpp
+++ b/libunwindstack/tests/RegsTest.cpp
@@ -58,6 +58,8 @@
       : RegsImpl<TypeParam>(total_regs, regs_sp, return_loc) {}
   virtual ~RegsTestImpl() = default;
 
+  uint32_t MachineType() override { return 0; }
+
   uint64_t GetAdjustedPc(uint64_t, Elf*) override { return 0; }
   void SetFromRaw() override {}
   bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; }
diff --git a/libunwindstack/tests/UnwindTest.cpp b/libunwindstack/tests/UnwindTest.cpp
index 3c69e2a..2fc3a38 100644
--- a/libunwindstack/tests/UnwindTest.cpp
+++ b/libunwindstack/tests/UnwindTest.cpp
@@ -206,8 +206,7 @@
   RemoteMaps maps(pid);
   ASSERT_TRUE(maps.Parse());
   MemoryRemote memory(pid);
-  uint32_t machine_type;
-  std::unique_ptr<Regs> regs(Regs::RemoteGet(pid, &machine_type));
+  std::unique_ptr<Regs> regs(Regs::RemoteGet(pid));
   ASSERT_TRUE(regs.get() != nullptr);
 
   VerifyUnwind(pid, &memory, &maps, regs.get(), kFunctionOrder);
@@ -254,7 +253,7 @@
 
   LocalMaps maps;
   ASSERT_TRUE(maps.Parse());
-  std::unique_ptr<Regs> regs(Regs::CreateFromUcontext(Regs::GetMachineType(), ucontext));
+  std::unique_ptr<Regs> regs(Regs::CreateFromUcontext(Regs::CurrentMachineType(), ucontext));
   MemoryLocal memory;
 
   VerifyUnwind(tid.load(), &memory, &maps, regs.get(), kFunctionOrder);
@@ -293,8 +292,7 @@
   RemoteMaps maps(pid);
   ASSERT_TRUE(maps.Parse());
   MemoryRemote memory(pid);
-  uint32_t machine_type;
-  std::unique_ptr<Regs> regs(Regs::RemoteGet(pid, &machine_type));
+  std::unique_ptr<Regs> regs(Regs::RemoteGet(pid));
   ASSERT_TRUE(regs.get() != nullptr);
 
   VerifyUnwind(pid, &memory, &maps, regs.get(), kFunctionSignalOrder);
diff --git a/libunwindstack/tools/unwind.cpp b/libunwindstack/tools/unwind.cpp
index 642105a..c1077f8 100644
--- a/libunwindstack/tools/unwind.cpp
+++ b/libunwindstack/tools/unwind.cpp
@@ -62,8 +62,7 @@
     return;
   }
 
-  uint32_t machine_type;
-  unwindstack::Regs* regs = unwindstack::Regs::RemoteGet(pid, &machine_type);
+  unwindstack::Regs* regs = unwindstack::Regs::RemoteGet(pid);
   if (regs == nullptr) {
     printf("Unable to get remote reg data\n");
     return;
@@ -71,7 +70,7 @@
 
   bool bits32 = true;
   printf("ABI: ");
-  switch (machine_type) {
+  switch (regs->MachineType()) {
     case EM_ARM:
       printf("arm");
       break;