Add ability to read jit gdb data.

Changes:
- New JitDebug class to handle all of the jit gdb interface.
- Add unit tests for all, along with new offline test using debug data.
- Add new Memory type called MemoryOfflineParts that has multiple
  MemoryOffline objects to support the offline test.
- Update the tools to use the JitDebug object.
- Modify libbacktrace to use the JitDebug, but only looking in libart.so
  and libartd.so.
- Change the Format32Bits to Is32Bit since it's more accurate and I use
  it in a different context where original name didn't make sense.
- Add a new function to find global variables in an elf file
  (GetGlobalVariable).
- Add a new function to determine if a pc is valid for this elf (IsValidPc).

Bug: 68396769

Test: Ran new unit tests. Added new offline test that uses jit debug data.
Test: Ran art test that generates jit data and verified a crash unwinds
Test: through the jit data.
Change-Id: I6e7ee2f5bab2242028a06feece156dff21c0a974
diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp
index df1642e..0e3ab2c 100644
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -43,6 +43,30 @@
   }
 }
 
+bool ElfInterface::IsValidPc(uint64_t pc) {
+  if (!pt_loads_.empty()) {
+    for (auto& entry : pt_loads_) {
+      uint64_t start = entry.second.table_offset;
+      uint64_t end = start + entry.second.table_size;
+      if (pc >= start && pc < end) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  // No PT_LOAD data, look for a fde for this pc in the section data.
+  if (debug_frame_ != nullptr && debug_frame_->GetFdeFromPc(pc) != nullptr) {
+    return true;
+  }
+
+  if (eh_frame_ != nullptr && eh_frame_->GetFdeFromPc(pc) != nullptr) {
+    return true;
+  }
+
+  return false;
+}
+
 Memory* ElfInterface::CreateGnuDebugdataMemory() {
   if (gnu_debugdata_offset_ == 0 || gnu_debugdata_size_ == 0) {
     return nullptr;
@@ -225,6 +249,10 @@
         return false;
       }
       dynamic_offset_ = phdr.p_offset;
+      if (!memory_->ReadField(offset, &phdr, &phdr.p_vaddr, sizeof(phdr.p_vaddr))) {
+        return false;
+      }
+      dynamic_vaddr_ = phdr.p_vaddr;
       if (!memory_->ReadField(offset, &phdr, &phdr.p_memsz, sizeof(phdr.p_memsz))) {
         return false;
       }
@@ -386,6 +414,20 @@
   return false;
 }
 
+template <typename SymType>
+bool ElfInterface::GetGlobalVariableWithTemplate(const std::string& name, uint64_t* memory_address) {
+  if (symbols_.empty()) {
+    return false;
+  }
+
+  for (const auto symbol : symbols_) {
+    if (symbol->GetGlobal<SymType>(memory_, name, memory_address)) {
+      return true;
+    }
+  }
+  return false;
+}
+
 bool ElfInterface::Step(uint64_t pc, uint64_t load_bias, Regs* regs, Memory* process_memory,
                         bool* finished) {
   // Adjust the load bias to get the real relative pc.
@@ -451,6 +493,9 @@
 template bool ElfInterface::GetFunctionNameWithTemplate<Elf64_Sym>(uint64_t, uint64_t, std::string*,
                                                                    uint64_t*);
 
+template bool ElfInterface::GetGlobalVariableWithTemplate<Elf32_Sym>(const std::string&, uint64_t*);
+template bool ElfInterface::GetGlobalVariableWithTemplate<Elf64_Sym>(const std::string&, uint64_t*);
+
 template void ElfInterface::GetMaxSizeWithTemplate<Elf32_Ehdr>(Memory*, uint64_t*);
 template void ElfInterface::GetMaxSizeWithTemplate<Elf64_Ehdr>(Memory*, uint64_t*);