Elf interface for new unwinder.

This cl includes the code to read arm unwind information from a shared
library.

Bug: 23762183

Test: Passes all unit tests. I can dump the arm unwind information
Test: for an arm shared library.
Change-Id: I43501ea2eab843b81de8bd5128401dd1971af8d3
diff --git a/libunwindstack/Memory.cpp b/libunwindstack/Memory.cpp
index 336e4fe..1fcf842 100644
--- a/libunwindstack/Memory.cpp
+++ b/libunwindstack/Memory.cpp
@@ -48,14 +48,40 @@
   return false;
 }
 
+bool MemoryBuffer::Read(uint64_t addr, void* dst, size_t size) {
+  uint64_t last_read_byte;
+  if (__builtin_add_overflow(size, addr, &last_read_byte)) {
+    return false;
+  }
+  if (last_read_byte > raw_.size()) {
+    return false;
+  }
+  memcpy(dst, &raw_[addr], size);
+  return true;
+}
+
+uint8_t* MemoryBuffer::GetPtr(size_t offset) {
+  if (offset < raw_.size()) {
+    return &raw_[offset];
+  }
+  return nullptr;
+}
+
 MemoryFileAtOffset::~MemoryFileAtOffset() {
+  Clear();
+}
+
+void MemoryFileAtOffset::Clear() {
   if (data_) {
     munmap(&data_[-offset_], size_ + offset_);
     data_ = nullptr;
   }
 }
 
-bool MemoryFileAtOffset::Init(const std::string& file, uint64_t offset) {
+bool MemoryFileAtOffset::Init(const std::string& file, uint64_t offset, uint64_t size) {
+  // Clear out any previous data if it exists.
+  Clear();
+
   android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(file.c_str(), O_RDONLY | O_CLOEXEC)));
   if (fd == -1) {
     return false;
@@ -71,6 +97,10 @@
   offset_ = offset & (getpagesize() - 1);
   uint64_t aligned_offset = offset & ~(getpagesize() - 1);
   size_ = buf.st_size - aligned_offset;
+  if (size < (UINT64_MAX - offset_) && size + offset_ < size_) {
+    // Truncate the mapped size.
+    size_ = size + offset_;
+  }
   void* map = mmap(nullptr, size_, PROT_READ, MAP_PRIVATE, fd, aligned_offset);
   if (map == MAP_FAILED) {
     return false;
@@ -91,6 +121,12 @@
 }
 
 static bool PtraceRead(pid_t pid, uint64_t addr, long* value) {
+#if !defined(__LP64__)
+  // Cannot read an address greater than 32 bits.
+  if (addr > UINT32_MAX) {
+    return false;
+  }
+#endif
   // ptrace() returns -1 and sets errno when the operation fails.
   // To disambiguate -1 from a valid result, we clear errno beforehand.
   errno = 0;