Use Unwinder object for unwind tool.

Test: Ran unwind on arm and arm64 processes.
Change-Id: I8a2a3ed31482044fe51d7e0d8c7f5588d5aad81c
diff --git a/libunwindstack/tools/unwind.cpp b/libunwindstack/tools/unwind.cpp
index faac2ef..f2530d7 100644
--- a/libunwindstack/tools/unwind.cpp
+++ b/libunwindstack/tools/unwind.cpp
@@ -26,17 +26,11 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <android-base/stringprintf.h>
-
 #include <unwindstack/Elf.h>
-#include <unwindstack/MapInfo.h>
 #include <unwindstack/Maps.h>
 #include <unwindstack/Memory.h>
 #include <unwindstack/Regs.h>
+#include <unwindstack/Unwinder.h>
 
 static bool Attach(pid_t pid) {
   if (ptrace(PTRACE_ATTACH, pid, 0, 0) == -1) {
@@ -55,66 +49,6 @@
   return false;
 }
 
-static bool Detach(pid_t pid) {
-  return ptrace(PTRACE_DETACH, pid, 0, 0) == 0;
-}
-
-std::string GetFrameInfo(size_t frame_num, unwindstack::Regs* regs,
-                         const std::shared_ptr<unwindstack::Memory>& process_memory,
-                         unwindstack::MapInfo* map_info, uint64_t* rel_pc) {
-  bool bits32;
-  switch (regs->MachineType()) {
-    case EM_ARM:
-    case EM_386:
-      bits32 = true;
-      break;
-
-    default:
-      bits32 = false;
-  }
-
-  if (map_info == nullptr) {
-    if (bits32) {
-      return android::base::StringPrintf("  #%02zu pc %08" PRIx64, frame_num, regs->pc());
-    } else {
-      return android::base::StringPrintf("  #%02zu pc %016" PRIx64, frame_num, regs->pc());
-    }
-  }
-
-  unwindstack::Elf* elf = map_info->GetElf(process_memory, true);
-  *rel_pc = elf->GetRelPc(regs->pc(), map_info);
-  uint64_t adjusted_rel_pc = *rel_pc;
-  // Don't need to adjust the first frame pc.
-  if (frame_num != 0) {
-    adjusted_rel_pc = regs->GetAdjustedPc(*rel_pc, elf);
-  }
-
-  std::string line;
-  if (bits32) {
-    line = android::base::StringPrintf("  #%02zu pc %08" PRIx64, frame_num, adjusted_rel_pc);
-  } else {
-    line = android::base::StringPrintf("  #%02zu pc %016" PRIx64, frame_num, adjusted_rel_pc);
-  }
-  if (!map_info->name.empty()) {
-    line += "  " + map_info->name;
-    if (map_info->elf_offset != 0) {
-      line += android::base::StringPrintf(" (offset 0x%" PRIx64 ")", map_info->elf_offset);
-    }
-  } else {
-    line += android::base::StringPrintf("  <anonymous:%" PRIx64 ">", map_info->offset);
-  }
-  uint64_t func_offset;
-  std::string func_name;
-  if (elf->GetFunctionName(adjusted_rel_pc, &func_name, &func_offset)) {
-    line += " (" + func_name;
-    if (func_offset != 0) {
-      line += android::base::StringPrintf("+%" PRId64, func_offset);
-    }
-    line += ')';
-  }
-  return line;
-}
-
 void DoUnwind(pid_t pid) {
   unwindstack::RemoteMaps remote_maps(pid);
   if (!remote_maps.Parse()) {
@@ -149,48 +83,12 @@
   printf("\n");
 
   auto process_memory = unwindstack::Memory::CreateProcessMemory(pid);
-  bool return_address_attempt = false;
-  std::vector<std::string> frames;
-  for (size_t frame_num = 0; frame_num < 64; frame_num++) {
-    unwindstack::MapInfo* map_info = remote_maps.Find(regs->pc());
-    uint64_t rel_pc;
-    frames.push_back(GetFrameInfo(frame_num, regs, process_memory, map_info, &rel_pc));
-    bool stepped;
-    if (map_info == nullptr) {
-      stepped = false;
-    } else {
-      bool finished;
-      stepped =
-          map_info->elf->Step(rel_pc + map_info->elf_offset, regs, process_memory.get(), &finished);
-      if (stepped && finished) {
-        break;
-      }
-    }
-    if (!stepped) {
-      if (return_address_attempt) {
-        // We tried the return address and it didn't work, remove the last
-        // two frames. If this bad frame is the only frame, only remove
-        // the last frame.
-        frames.pop_back();
-        if (frame_num != 1) {
-          frames.pop_back();
-        }
-        break;
-      } else {
-        // Steping didn't work, try this secondary method.
-        if (!regs->SetPcFromReturnAddress(process_memory.get())) {
-          break;
-        }
-        return_address_attempt = true;
-      }
-    } else {
-      return_address_attempt = false;
-    }
-  }
+  unwindstack::Unwinder unwinder(128, &remote_maps, regs, process_memory);
+  unwinder.Unwind();
 
   // Print the frames.
-  for (auto& frame : frames) {
-    printf("%s\n", frame.c_str());
+  for (size_t i = 0; i < unwinder.NumFrames(); i++) {
+    printf("%s\n", unwinder.FormatFrame(i).c_str());
   }
 }
 
@@ -208,7 +106,7 @@
 
   DoUnwind(pid);
 
-  Detach(pid);
+  ptrace(PTRACE_DETACH, pid, 0, 0);
 
   return 0;
 }