Merge "libsync: Fix a double-free."
diff --git a/init/Android.bp b/init/Android.bp
index 8737def..672942e 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -119,7 +119,7 @@
         "init_first_stage.cpp",
         "keychords.cpp",
         "reboot.cpp",
-        "signal_handler.cpp",
+        "sigchld_handler.cpp",
         "ueventd.cpp",
         "watchdogd.cpp",
     ],
diff --git a/init/Android.mk b/init/Android.mk
index 23ada73..6c28517 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -48,7 +48,7 @@
     init_first_stage.cpp \
     keychords.cpp \
     reboot.cpp \
-    signal_handler.cpp \
+    sigchld_handler.cpp \
     ueventd.cpp \
     watchdogd.cpp \
 
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 140ef75..886c572 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -66,7 +66,6 @@
 #include "reboot.h"
 #include "rlimit_parser.h"
 #include "service.h"
-#include "signal_handler.h"
 #include "util.h"
 
 using namespace std::literals::string_literals;
diff --git a/init/init.cpp b/init/init.cpp
index 678f49f..c3e08fb 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <sys/epoll.h>
 #include <sys/mount.h>
+#include <sys/signalfd.h>
 #include <sys/sysmacros.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -51,7 +52,7 @@
 #include "reboot.h"
 #include "security.h"
 #include "selinux.h"
-#include "signal_handler.h"
+#include "sigchld_handler.h"
 #include "ueventd.h"
 #include "util.h"
 #include "watchdogd.h"
@@ -72,6 +73,7 @@
 std::string default_console = "/dev/console";
 
 static int epoll_fd = -1;
+static int sigterm_signal_fd = -1;
 
 static std::unique_ptr<Timer> waiting_for_prop(nullptr);
 static std::string wait_prop_name;
@@ -392,6 +394,41 @@
     sigaction(SIGTRAP, &action, nullptr);
 }
 
+static void HandleSigtermSignal() {
+    signalfd_siginfo siginfo;
+    ssize_t bytes_read = TEMP_FAILURE_RETRY(read(sigterm_signal_fd, &siginfo, sizeof(siginfo)));
+    if (bytes_read != sizeof(siginfo)) {
+        PLOG(ERROR) << "Failed to read siginfo from sigterm_signal_fd";
+        return;
+    }
+
+    if (siginfo.ssi_pid != 0) {
+        // Drop any userspace SIGTERM requests.
+        LOG(DEBUG) << "Ignoring SIGTERM from pid " << siginfo.ssi_pid;
+        return;
+    }
+
+    LOG(INFO) << "Handling SIGTERM, shutting system down";
+    HandlePowerctlMessage("shutdown");
+}
+
+static void InstallSigtermHandler() {
+    sigset_t mask;
+    sigemptyset(&mask);
+    sigaddset(&mask, SIGTERM);
+
+    if (sigprocmask(SIG_BLOCK, &mask, nullptr) == -1) {
+        PLOG(FATAL) << "failed to block SIGTERM";
+    }
+
+    sigterm_signal_fd = signalfd(-1, &mask, SFD_CLOEXEC);
+    if (sigterm_signal_fd == -1) {
+        PLOG(FATAL) << "failed to create signalfd for SIGTERM";
+    }
+
+    register_epoll_handler(sigterm_signal_fd, HandleSigtermSignal);
+}
+
 int main(int argc, char** argv) {
     if (!strcmp(basename(argv[0]), "ueventd")) {
         return ueventd_main(argc, argv);
@@ -527,7 +564,13 @@
         exit(1);
     }
 
-    signal_handler_init();
+    sigchld_handler_init();
+
+    if (!IsRebootCapable()) {
+        // If init does not have the CAP_SYS_BOOT capability, it is running in a container.
+        // In that case, receiving SIGTERM will cause the system to shut down.
+        InstallSigtermHandler();
+    }
 
     property_load_boot_defaults();
     export_oem_lock_status();
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 8c592cb..5f5ed40 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -45,6 +45,7 @@
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/properties.h>
+#include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <bootimg.h>
 #include <fs_mgr.h>
@@ -56,6 +57,7 @@
 #include "persistent_properties.h"
 #include "util.h"
 
+using android::base::StringPrintf;
 using android::base::Timer;
 
 #define RECOVERY_MOUNT_POINT "/recovery"
@@ -418,6 +420,20 @@
     }
   } else {
     if (check_mac_perms(name, source_ctx, &cr)) {
+      // sys.powerctl is a special property that is used to make the device reboot.  We want to log
+      // any process that sets this property to be able to accurately blame the cause of a shutdown.
+      if (name == "sys.powerctl") {
+        std::string cmdline_path = StringPrintf("proc/%d/cmdline", cr.pid);
+        std::string process_cmdline;
+        std::string process_log_string;
+        if (android::base::ReadFileToString(cmdline_path, &process_cmdline)) {
+          // Since cmdline is null deliminated, .c_str() conveniently gives us just the process path.
+          process_log_string = StringPrintf(" (%s)", process_cmdline.c_str());
+        }
+        LOG(INFO) << "Received sys.powerctl='" << value << "' from pid: " << cr.pid
+                  << process_log_string;
+      }
+
       uint32_t result = property_set(name, value);
       if (!legacy_protocol) {
         socket.SendUint32(result);
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 891ca03..049c952 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -54,7 +54,7 @@
 #include "init.h"
 #include "property_service.h"
 #include "service.h"
-#include "signal_handler.h"
+#include "sigchld_handler.h"
 
 using android::base::StringPrintf;
 using android::base::Timer;
@@ -169,9 +169,7 @@
                  << stat;
 }
 
-// Determines whether the system is capable of rebooting. This is conservative,
-// so if any of the attempts to determine this fail, it will still return true.
-static bool IsRebootCapable() {
+bool IsRebootCapable() {
     if (!CAP_IS_SUPPORTED(CAP_SYS_BOOT)) {
         PLOG(WARNING) << "CAP_SYS_BOOT is not supported";
         return true;
diff --git a/init/reboot.h b/init/reboot.h
index ece407f..1c58bd1 100644
--- a/init/reboot.h
+++ b/init/reboot.h
@@ -38,6 +38,10 @@
 // Parses and handles a setprop sys.powerctl message.
 bool HandlePowerctlMessage(const std::string& command);
 
+// Determines whether the system is capable of rebooting. This is conservative,
+// so if any of the attempts to determine this fail, it will still return true.
+bool IsRebootCapable();
+
 }  // namespace init
 }  // namespace android
 
diff --git a/init/signal_handler.cpp b/init/sigchld_handler.cpp
similarity index 98%
rename from init/signal_handler.cpp
rename to init/sigchld_handler.cpp
index 9e49c48..8fc9956 100644
--- a/init/signal_handler.cpp
+++ b/init/sigchld_handler.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "signal_handler.h"
+#include "sigchld_handler.h"
 
 #include <signal.h>
 #include <string.h>
@@ -115,7 +115,7 @@
     }
 }
 
-void signal_handler_init() {
+void sigchld_handler_init() {
     // Create a signalling mechanism for SIGCHLD.
     int s[2];
     if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, s) == -1) {
diff --git a/init/signal_handler.h b/init/sigchld_handler.h
similarity index 88%
rename from init/signal_handler.h
rename to init/sigchld_handler.h
index 9362be5..c86dc8d 100644
--- a/init/signal_handler.h
+++ b/init/sigchld_handler.h
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-#ifndef _INIT_SIGNAL_HANDLER_H_
-#define _INIT_SIGNAL_HANDLER_H_
+#ifndef _INIT_SIGCHLD_HANDLER_H_
+#define _INIT_SIGCHLD_HANDLER_H_
 
 namespace android {
 namespace init {
 
 void ReapAnyOutstandingChildren();
 
-void signal_handler_init(void);
+void sigchld_handler_init(void);
 
 }  // namespace init
 }  // namespace android
diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp
index 3b2f38e..61812ab 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -41,8 +41,7 @@
 #include "UnwindStack.h"
 #include "UnwindStackMap.h"
 
-static std::string GetFunctionName(pid_t pid, BacktraceMap* back_map, uintptr_t pc,
-                                   uintptr_t* offset) {
+static std::string GetFunctionName(BacktraceMap* back_map, uintptr_t pc, uintptr_t* offset) {
   *offset = 0;
   unwindstack::Maps* maps = reinterpret_cast<UnwindStackMap*>(back_map)->stack_maps();
 
@@ -52,7 +51,8 @@
     return "";
   }
 
-  unwindstack::Elf* elf = map_info->GetElf(pid, true);
+  UnwindStackMap* stack_map = reinterpret_cast<UnwindStackMap*>(back_map);
+  unwindstack::Elf* elf = map_info->GetElf(stack_map->process_memory(), true);
 
   std::string name;
   uint64_t func_offset;
@@ -68,10 +68,10 @@
   return library == "libunwindstack.so" || library == "libbacktrace.so";
 }
 
-static bool Unwind(pid_t pid, unwindstack::Memory* memory, unwindstack::Regs* regs,
-                   BacktraceMap* back_map, std::vector<backtrace_frame_data_t>* frames,
-                   size_t num_ignore_frames) {
-  unwindstack::Maps* maps = reinterpret_cast<UnwindStackMap*>(back_map)->stack_maps();
+static bool Unwind(unwindstack::Regs* regs, BacktraceMap* back_map,
+                   std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames) {
+  UnwindStackMap* stack_map = reinterpret_cast<UnwindStackMap*>(back_map);
+  unwindstack::Maps* maps = stack_map->stack_maps();
   bool adjust_rel_pc = false;
   size_t num_frames = 0;
   frames->clear();
@@ -84,7 +84,7 @@
       break;
     }
 
-    unwindstack::Elf* elf = map_info->GetElf(pid, true);
+    unwindstack::Elf* elf = map_info->GetElf(stack_map->process_memory(), true);
     uint64_t rel_pc = elf->GetRelPc(regs->pc(), map_info);
 
     bool skip_frame = num_frames == 0 && IsUnwindLibrary(map_info->name);
@@ -137,7 +137,7 @@
       break;
     }
 
-    if (!elf->Step(rel_pc + map_info->elf_offset, regs, memory)) {
+    if (!elf->Step(rel_pc + map_info->elf_offset, regs, stack_map->process_memory().get())) {
       break;
     }
   }
@@ -146,10 +146,10 @@
 }
 
 UnwindStackCurrent::UnwindStackCurrent(pid_t pid, pid_t tid, BacktraceMap* map)
-    : BacktraceCurrent(pid, tid, map), memory_(new unwindstack::MemoryLocal) {}
+    : BacktraceCurrent(pid, tid, map) {}
 
 std::string UnwindStackCurrent::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) {
-  return ::GetFunctionName(Pid(), GetMap(), pc, offset);
+  return ::GetFunctionName(GetMap(), pc, offset);
 }
 
 bool UnwindStackCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t* ucontext) {
@@ -165,14 +165,14 @@
   }
 
   error_ = BACKTRACE_UNWIND_NO_ERROR;
-  return ::Unwind(getpid(), memory_.get(), regs.get(), GetMap(), &frames_, num_ignore_frames);
+  return ::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames);
 }
 
 UnwindStackPtrace::UnwindStackPtrace(pid_t pid, pid_t tid, BacktraceMap* map)
-    : BacktracePtrace(pid, tid, map), memory_(new unwindstack::MemoryRemote(pid)) {}
+    : BacktracePtrace(pid, tid, map) {}
 
 std::string UnwindStackPtrace::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) {
-  return ::GetFunctionName(Pid(), GetMap(), pc, offset);
+  return ::GetFunctionName(GetMap(), pc, offset);
 }
 
 bool UnwindStackPtrace::Unwind(size_t num_ignore_frames, ucontext_t* context) {
@@ -185,7 +185,7 @@
   }
 
   error_ = BACKTRACE_UNWIND_NO_ERROR;
-  return ::Unwind(Pid(), memory_.get(), regs.get(), GetMap(), &frames_, num_ignore_frames);
+  return ::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames);
 }
 
 Backtrace* Backtrace::CreateNew(pid_t pid, pid_t tid, BacktraceMap* map) {
diff --git a/libbacktrace/UnwindStack.h b/libbacktrace/UnwindStack.h
index 32d1f51..be9ef63 100644
--- a/libbacktrace/UnwindStack.h
+++ b/libbacktrace/UnwindStack.h
@@ -35,9 +35,6 @@
   std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) override;
 
   bool UnwindFromContext(size_t num_ignore_frames, ucontext_t* ucontext) override;
-
- private:
-  std::unique_ptr<unwindstack::Memory> memory_;
 };
 
 class UnwindStackPtrace : public BacktracePtrace {
@@ -48,9 +45,6 @@
   bool Unwind(size_t num_ignore_frames, ucontext_t* context) override;
 
   std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset);
-
- private:
-  std::unique_ptr<unwindstack::Memory> memory_;
 };
 
 #endif  // _LIBBACKTRACE_UNWIND_STACK_H
diff --git a/libbacktrace/UnwindStackMap.cpp b/libbacktrace/UnwindStackMap.cpp
index ba9fd87..d4a2444 100644
--- a/libbacktrace/UnwindStackMap.cpp
+++ b/libbacktrace/UnwindStackMap.cpp
@@ -36,6 +36,9 @@
     stack_maps_.reset(new unwindstack::RemoteMaps(pid_));
   }
 
+  // Create the process memory object.
+  process_memory_ = unwindstack::Memory::CreateProcessMemory(pid_);
+
   if (!stack_maps_->Parse()) {
     return false;
   }
@@ -68,7 +71,7 @@
   if (map_info == nullptr) {
     return;
   }
-  unwindstack::Elf* elf = map_info->GetElf(pid_, true);
+  unwindstack::Elf* elf = map_info->GetElf(process_memory_, true);
   map->load_bias = elf->GetLoadBias();
 }
 
diff --git a/libbacktrace/UnwindStackMap.h b/libbacktrace/UnwindStackMap.h
index 7885b74..b93b340 100644
--- a/libbacktrace/UnwindStackMap.h
+++ b/libbacktrace/UnwindStackMap.h
@@ -20,6 +20,8 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <memory>
+
 #include <backtrace/BacktraceMap.h>
 #include <unwindstack/Maps.h>
 
@@ -34,8 +36,11 @@
 
   unwindstack::Maps* stack_maps() { return stack_maps_.get(); }
 
+  const std::shared_ptr<unwindstack::Memory>& process_memory() { return process_memory_; }
+
  protected:
   std::unique_ptr<unwindstack::Maps> stack_maps_;
+  std::shared_ptr<unwindstack::Memory> process_memory_;
 };
 
 #endif  // _LIBBACKTRACE_UNWINDSTACK_MAP_H
diff --git a/libgrallocusage/Android.bp b/libgrallocusage/Android.bp
index 54bfee5..cf03868 100644
--- a/libgrallocusage/Android.bp
+++ b/libgrallocusage/Android.bp
@@ -14,6 +14,7 @@
 
 cc_library_static {
     name: "libgrallocusage",
+    vendor_available: true,
     cppflags: [
         "-Weverything",
         "-Werror",
@@ -26,4 +27,5 @@
     srcs: ["GrallocUsageConversion.cpp"],
     export_include_dirs: ["include"],
     shared_libs: ["android.hardware.graphics.allocator@2.0"],
+    header_libs: ["libhardware_headers"],
 }
diff --git a/liblog/local_logger.c b/liblog/local_logger.c
index 522867d..563cb3f 100644
--- a/liblog/local_logger.c
+++ b/liblog/local_logger.c
@@ -222,6 +222,7 @@
       log->last[logId] = node->prev;
     }
     list_remove(node);
+    LOG_ALWAYS_FATAL_IF(node == log->last[logId], "corrupted list");
     free(e);
   }
   /* add entry to list */
diff --git a/liblog/logprint.c b/liblog/logprint.c
index b62f8b4..a2839bf 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -250,6 +250,7 @@
   while (!list_empty(&convertHead)) {
     struct listnode* node = list_head(&convertHead);
     list_remove(node);
+    LOG_ALWAYS_FATAL_IF(node == list_head(&convertHead), "corrupted list");
     free(node);
   }
 }
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index b971a9e..32ba692 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -35,6 +35,10 @@
 cc_library {
     name: "libunwindstack",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+        support_system_process: true,
+    },
     defaults: ["libunwindstack_flags"],
     export_include_dirs: ["include"],
 
@@ -57,6 +61,13 @@
         "Symbols.cpp",
     ],
 
+    target: {
+        // Always disable optimizations for host to make it easier to debug.
+        linux: {
+            cflags: ["-O0", "-g"],
+        },
+    },
+
     arch: {
         x86: {
             srcs: ["AsmGetRegsX86.S"],
@@ -97,7 +108,6 @@
         "tests/ElfTest.cpp",
         "tests/ElfTestUtils.cpp",
         "tests/LogFake.cpp",
-        "tests/MapInfoCreateMemoryTest.cpp",
         "tests/MapInfoGetElfTest.cpp",
         "tests/MapsTest.cpp",
         "tests/MemoryBufferTest.cpp",
diff --git a/libunwindstack/MapInfo.cpp b/libunwindstack/MapInfo.cpp
index 3272215..96f2cb4 100644
--- a/libunwindstack/MapInfo.cpp
+++ b/libunwindstack/MapInfo.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <sys/mman.h>
 #include <sys/types.h>
 #include <unistd.h>
 
@@ -76,40 +77,39 @@
   return memory.release();
 }
 
-Memory* MapInfo::CreateMemory(pid_t pid) {
+Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) {
   if (end <= start) {
     return nullptr;
   }
 
   elf_offset = 0;
 
+  // Fail on device maps.
+  if (flags & MAPS_FLAGS_DEVICE_MAP) {
+    return nullptr;
+  }
+
   // First try and use the file associated with the info.
   if (!name.empty()) {
-    // Fail on device maps.
-    if (flags & MAPS_FLAGS_DEVICE_MAP) {
-      return nullptr;
-    }
     Memory* memory = GetFileMemory();
     if (memory != nullptr) {
       return memory;
     }
   }
 
-  Memory* memory;
-  if (pid == getpid()) {
-    memory = new MemoryLocal();
-  } else {
-    memory = new MemoryRemote(pid);
+  // If the map isn't readable, don't bother trying to read from process memory.
+  if (!(flags & PROT_READ)) {
+    return nullptr;
   }
-  return new MemoryRange(memory, start, end);
+  return new MemoryRange(process_memory, start, end);
 }
 
-Elf* MapInfo::GetElf(pid_t pid, bool init_gnu_debugdata) {
+Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, bool init_gnu_debugdata) {
   if (elf) {
     return elf;
   }
 
-  elf = new Elf(CreateMemory(pid));
+  elf = new Elf(CreateMemory(process_memory));
   if (elf->Init() && init_gnu_debugdata) {
     elf->InitGnuDebugdata();
   }
diff --git a/libunwindstack/Memory.cpp b/libunwindstack/Memory.cpp
index 8c36055..32753df 100644
--- a/libunwindstack/Memory.cpp
+++ b/libunwindstack/Memory.cpp
@@ -52,6 +52,13 @@
   return false;
 }
 
+std::shared_ptr<Memory> Memory::CreateProcessMemory(pid_t pid) {
+  if (pid == getpid()) {
+    return std::shared_ptr<Memory>(new MemoryLocal());
+  }
+  return std::shared_ptr<Memory>(new MemoryRemote(pid));
+}
+
 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)) {
@@ -249,7 +256,7 @@
   return true;
 }
 
-MemoryRange::MemoryRange(Memory* memory, uint64_t begin, uint64_t end)
+MemoryRange::MemoryRange(const std::shared_ptr<Memory>& memory, uint64_t begin, uint64_t end)
     : memory_(memory), begin_(begin), length_(end - begin) {
   CHECK(end > begin);
 }
diff --git a/libunwindstack/include/unwindstack/MapInfo.h b/libunwindstack/include/unwindstack/MapInfo.h
index b8ba925..f108766 100644
--- a/libunwindstack/include/unwindstack/MapInfo.h
+++ b/libunwindstack/include/unwindstack/MapInfo.h
@@ -40,10 +40,13 @@
   // instead of a portion of the file.
   uint64_t elf_offset;
 
-  Memory* GetFileMemory();
-  Memory* CreateMemory(pid_t pid);
   // This function guarantees it will never return nullptr.
-  Elf* GetElf(pid_t pid, bool init_gnu_debugdata = false);
+  Elf* GetElf(const std::shared_ptr<Memory>& process_memory, bool init_gnu_debugdata = false);
+
+ private:
+  Memory* GetFileMemory();
+
+  Memory* CreateMemory(const std::shared_ptr<Memory>& process_memory);
 };
 
 }  // namespace unwindstack
diff --git a/libunwindstack/include/unwindstack/Memory.h b/libunwindstack/include/unwindstack/Memory.h
index 0c05266..183b899 100644
--- a/libunwindstack/include/unwindstack/Memory.h
+++ b/libunwindstack/include/unwindstack/Memory.h
@@ -21,6 +21,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -31,6 +32,8 @@
   Memory() = default;
   virtual ~Memory() = default;
 
+  static std::shared_ptr<Memory> CreateProcessMemory(pid_t pid);
+
   virtual bool ReadString(uint64_t addr, std::string* string, uint64_t max_read = UINT64_MAX);
 
   virtual bool Read(uint64_t addr, void* dst, size_t size) = 0;
@@ -125,13 +128,13 @@
 
 class MemoryRange : public Memory {
  public:
-  MemoryRange(Memory* memory, uint64_t begin, uint64_t end);
-  virtual ~MemoryRange() { delete memory_; }
+  MemoryRange(const std::shared_ptr<Memory>& memory, uint64_t begin, uint64_t end);
+  virtual ~MemoryRange() = default;
 
   bool Read(uint64_t addr, void* dst, size_t size) override;
 
  private:
-  Memory* memory_;
+  std::shared_ptr<Memory> memory_;
   uint64_t begin_;
   uint64_t length_;
 };
diff --git a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
index 2aab9c6..d2aad49 100644
--- a/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
+++ b/libunwindstack/tests/MapInfoCreateMemoryTest.cpp
@@ -34,6 +34,8 @@
 #include <unwindstack/MapInfo.h>
 #include <unwindstack/Memory.h>
 
+#include "MemoryFake.h"
+
 namespace unwindstack {
 
 class MapInfoCreateMemoryTest : public ::testing::Test {
@@ -71,6 +73,14 @@
     InitElf<Elf64_Ehdr, Elf64_Shdr>(elf64_at_map_.fd, 0x2000, 0x3000, ELFCLASS64);
   }
 
+  void SetUp() override {
+    memory_ = new MemoryFake;
+    process_memory_.reset(memory_);
+  }
+
+  MemoryFake* memory_;
+  std::shared_ptr<Memory> process_memory_;
+
   static TemporaryFile elf_;
 
   static TemporaryFile elf_at_100_;
@@ -86,17 +96,16 @@
 TEST_F(MapInfoCreateMemoryTest, end_le_start) {
   MapInfo info{.start = 0x100, .end = 0x100, .offset = 0, .name = elf_.path};
 
-  std::unique_ptr<Memory> memory;
-  memory.reset(info.CreateMemory(getpid()));
+  std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() == nullptr);
 
   info.end = 0xff;
-  memory.reset(info.CreateMemory(getpid()));
+  memory.reset(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() == nullptr);
 
   // Make sure this test is valid.
   info.end = 0x101;
-  memory.reset(info.CreateMemory(getpid()));
+  memory.reset(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
 }
 
@@ -105,7 +114,7 @@
 TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_full_file) {
   MapInfo info{.start = 0x100, .end = 0x200, .offset = 0x100, .name = elf_.path};
 
-  std::unique_ptr<Memory> memory(info.CreateMemory(getpid()));
+  std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
   ASSERT_EQ(0x100U, info.elf_offset);
 
@@ -126,7 +135,7 @@
 TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file) {
   MapInfo info{.start = 0x100, .end = 0x200, .offset = 0x100, .name = elf_at_100_.path};
 
-  std::unique_ptr<Memory> memory(info.CreateMemory(getpid()));
+  std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
   ASSERT_EQ(0U, info.elf_offset);
 
@@ -149,7 +158,7 @@
 TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file_whole_elf32) {
   MapInfo info{.start = 0x5000, .end = 0x6000, .offset = 0x1000, .name = elf32_at_map_.path};
 
-  std::unique_ptr<Memory> memory(info.CreateMemory(getpid()));
+  std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
   ASSERT_EQ(0U, info.elf_offset);
 
@@ -165,7 +174,7 @@
 TEST_F(MapInfoCreateMemoryTest, file_backed_non_zero_offset_partial_file_whole_elf64) {
   MapInfo info{.start = 0x7000, .end = 0x8000, .offset = 0x2000, .name = elf64_at_map_.path};
 
-  std::unique_ptr<Memory> memory(info.CreateMemory(getpid()));
+  std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
   ASSERT_EQ(0U, info.elf_offset);
 
@@ -187,81 +196,38 @@
   info.start = reinterpret_cast<uint64_t>(buffer.data());
   info.end = info.start + buffer.size();
   info.offset = 0;
-  std::unique_ptr<Memory> memory;
 
   info.flags = 0x8000;
   info.name = "/dev/something";
-  memory.reset(info.CreateMemory(getpid()));
+  std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() == nullptr);
 }
 
-TEST_F(MapInfoCreateMemoryTest, local_memory) {
-  // Set up some memory for a valid local memory object.
+TEST_F(MapInfoCreateMemoryTest, process_memory) {
+  MapInfo info;
+  info.start = 0x2000;
+  info.end = 0x3000;
+  info.offset = 0;
+
+  // Verify that the the process_memory object is used, so seed it
+  // with memory.
   std::vector<uint8_t> buffer(1024);
   for (size_t i = 0; i < buffer.size(); i++) {
     buffer[i] = i % 256;
   }
+  memory_->SetMemory(info.start, buffer.data(), buffer.size());
 
-  MapInfo info;
-  info.start = reinterpret_cast<uint64_t>(buffer.data());
-  info.end = info.start + buffer.size();
-  info.offset = 0;
-
-  std::unique_ptr<Memory> memory;
-  memory.reset(info.CreateMemory(getpid()));
+  std::unique_ptr<Memory> memory(info.CreateMemory(process_memory_));
   ASSERT_TRUE(memory.get() != nullptr);
 
-  std::vector<uint8_t> read_buffer(1024);
-  ASSERT_TRUE(memory->Read(0, read_buffer.data(), read_buffer.size()));
-  for (size_t i = 0; i < read_buffer.size(); i++) {
-    ASSERT_EQ(i % 256, read_buffer[i]) << "Failed at byte " << i;
+  memset(buffer.data(), 0, buffer.size());
+  ASSERT_TRUE(memory->Read(0, buffer.data(), buffer.size()));
+  for (size_t i = 0; i < buffer.size(); i++) {
+    ASSERT_EQ(i % 256, buffer[i]) << "Failed at byte " << i;
   }
 
-  ASSERT_FALSE(memory->Read(read_buffer.size(), read_buffer.data(), 1));
-}
-
-TEST_F(MapInfoCreateMemoryTest, remote_memory) {
-  std::vector<uint8_t> buffer(1024);
-  memset(buffer.data(), 0xa, buffer.size());
-
-  pid_t pid;
-  if ((pid = fork()) == 0) {
-    while (true)
-      ;
-    exit(1);
-  }
-  ASSERT_LT(0, pid);
-
-  ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) != -1);
-  uint64_t iterations = 0;
-  siginfo_t si;
-  while (TEMP_FAILURE_RETRY(ptrace(PTRACE_GETSIGINFO, pid, 0, &si)) < 0 && errno == ESRCH) {
-    usleep(30);
-    iterations++;
-    ASSERT_LT(iterations, 500000000ULL);
-  }
-
-  MapInfo info;
-  info.start = reinterpret_cast<uint64_t>(buffer.data());
-  info.end = info.start + buffer.size();
-  info.offset = 0;
-
-  std::unique_ptr<Memory> memory;
-  memory.reset(info.CreateMemory(pid));
-  ASSERT_TRUE(memory.get() != nullptr);
-  // Set the local memory to a different value to guarantee we are reading
-  // from the remote process.
-  memset(buffer.data(), 0x1, buffer.size());
-  std::vector<uint8_t> read_buffer(1024);
-  ASSERT_TRUE(memory->Read(0, read_buffer.data(), read_buffer.size()));
-  for (size_t i = 0; i < read_buffer.size(); i++) {
-    ASSERT_EQ(0xaU, read_buffer[i]) << "Failed at byte " << i;
-  }
-
-  ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0);
-
-  kill(pid, SIGKILL);
-  ASSERT_EQ(pid, wait(nullptr));
+  // Try to read outside of the map size.
+  ASSERT_FALSE(memory->Read(buffer.size(), buffer.data(), 1));
 }
 
 }  // namespace unwindstack
diff --git a/libunwindstack/tests/MapInfoGetElfTest.cpp b/libunwindstack/tests/MapInfoGetElfTest.cpp
index abfa172..0b70d13 100644
--- a/libunwindstack/tests/MapInfoGetElfTest.cpp
+++ b/libunwindstack/tests/MapInfoGetElfTest.cpp
@@ -32,43 +32,57 @@
 
 #include <unwindstack/Elf.h>
 #include <unwindstack/MapInfo.h>
+#include <unwindstack/Maps.h>
 #include <unwindstack/Memory.h>
 
 #include "ElfTestUtils.h"
+#include "MemoryFake.h"
 
 namespace unwindstack {
 
 class MapInfoGetElfTest : public ::testing::Test {
  protected:
   void SetUp() override {
-    map_ = mmap(nullptr, kMapSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-    ASSERT_NE(MAP_FAILED, map_);
-
-    uint64_t start = reinterpret_cast<uint64_t>(map_);
-    info_.reset(new MapInfo{.start = start, .end = start + 1024, .offset = 0, .name = ""});
+    memory_ = new MemoryFake;
+    process_memory_.reset(memory_);
   }
 
-  void TearDown() override { munmap(map_, kMapSize); }
+  template <typename Ehdr, typename Shdr>
+  static void InitElf(uint64_t sh_offset, Ehdr* ehdr, uint8_t class_type, uint8_t machine_type) {
+    memset(ehdr, 0, sizeof(*ehdr));
+    memcpy(ehdr->e_ident, ELFMAG, SELFMAG);
+    ehdr->e_ident[EI_CLASS] = class_type;
+    ehdr->e_machine = machine_type;
+    ehdr->e_shoff = sh_offset;
+    ehdr->e_shentsize = sizeof(Shdr) + 100;
+    ehdr->e_shnum = 4;
+  }
 
   const size_t kMapSize = 4096;
 
-  void* map_ = nullptr;
-  std::unique_ptr<MapInfo> info_;
+  std::shared_ptr<Memory> process_memory_;
+  MemoryFake* memory_;
+
+  TemporaryFile elf_;
 };
 
 TEST_F(MapInfoGetElfTest, invalid) {
+  MapInfo info{.start = 0x1000, .end = 0x2000, .offset = 0, .flags = PROT_READ, .name = ""};
+
   // The map is empty, but this should still create an invalid elf object.
-  std::unique_ptr<Elf> elf(info_->GetElf(getpid(), false));
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, false));
   ASSERT_TRUE(elf.get() != nullptr);
   ASSERT_FALSE(elf->valid());
 }
 
 TEST_F(MapInfoGetElfTest, valid32) {
+  MapInfo info{.start = 0x3000, .end = 0x4000, .offset = 0, .flags = PROT_READ, .name = ""};
+
   Elf32_Ehdr ehdr;
   TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
-  memcpy(map_, &ehdr, sizeof(ehdr));
+  memory_->SetMemory(0x3000, &ehdr, sizeof(ehdr));
 
-  std::unique_ptr<Elf> elf(info_->GetElf(getpid(), false));
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, false));
   ASSERT_TRUE(elf.get() != nullptr);
   ASSERT_TRUE(elf->valid());
   EXPECT_EQ(static_cast<uint32_t>(EM_ARM), elf->machine_type());
@@ -76,11 +90,13 @@
 }
 
 TEST_F(MapInfoGetElfTest, valid64) {
+  MapInfo info{.start = 0x8000, .end = 0x9000, .offset = 0, .flags = PROT_READ, .name = ""};
+
   Elf64_Ehdr ehdr;
   TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, EM_AARCH64);
-  memcpy(map_, &ehdr, sizeof(ehdr));
+  memory_->SetMemory(0x8000, &ehdr, sizeof(ehdr));
 
-  std::unique_ptr<Elf> elf(info_->GetElf(getpid(), false));
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, false));
   ASSERT_TRUE(elf.get() != nullptr);
   ASSERT_TRUE(elf->valid());
   EXPECT_EQ(static_cast<uint32_t>(EM_AARCH64), elf->machine_type());
@@ -88,12 +104,14 @@
 }
 
 TEST_F(MapInfoGetElfTest, gnu_debugdata_do_not_init32) {
-  TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(
-      ELFCLASS32, EM_ARM, false, [&](uint64_t offset, const void* ptr, size_t size) {
-        memcpy(&reinterpret_cast<uint8_t*>(map_)[offset], ptr, size);
-      });
+  MapInfo info{.start = 0x4000, .end = 0x8000, .offset = 0, .flags = PROT_READ, .name = ""};
 
-  std::unique_ptr<Elf> elf(info_->GetElf(getpid(), false));
+  TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(ELFCLASS32, EM_ARM, false,
+                                               [&](uint64_t offset, const void* ptr, size_t size) {
+                                                 memory_->SetMemory(0x4000 + offset, ptr, size);
+                                               });
+
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, false));
   ASSERT_TRUE(elf.get() != nullptr);
   ASSERT_TRUE(elf->valid());
   EXPECT_EQ(static_cast<uint32_t>(EM_ARM), elf->machine_type());
@@ -102,12 +120,14 @@
 }
 
 TEST_F(MapInfoGetElfTest, gnu_debugdata_do_not_init64) {
-  TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(
-      ELFCLASS64, EM_AARCH64, false, [&](uint64_t offset, const void* ptr, size_t size) {
-        memcpy(&reinterpret_cast<uint8_t*>(map_)[offset], ptr, size);
-      });
+  MapInfo info{.start = 0x6000, .end = 0x8000, .offset = 0, .flags = PROT_READ, .name = ""};
 
-  std::unique_ptr<Elf> elf(info_->GetElf(getpid(), false));
+  TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(ELFCLASS64, EM_AARCH64, false,
+                                               [&](uint64_t offset, const void* ptr, size_t size) {
+                                                 memory_->SetMemory(0x6000 + offset, ptr, size);
+                                               });
+
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, false));
   ASSERT_TRUE(elf.get() != nullptr);
   ASSERT_TRUE(elf->valid());
   EXPECT_EQ(static_cast<uint32_t>(EM_AARCH64), elf->machine_type());
@@ -116,12 +136,14 @@
 }
 
 TEST_F(MapInfoGetElfTest, gnu_debugdata_init32) {
-  TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(
-      ELFCLASS32, EM_ARM, true, [&](uint64_t offset, const void* ptr, size_t size) {
-        memcpy(&reinterpret_cast<uint8_t*>(map_)[offset], ptr, size);
-      });
+  MapInfo info{.start = 0x2000, .end = 0x3000, .offset = 0, .flags = PROT_READ, .name = ""};
 
-  std::unique_ptr<Elf> elf(info_->GetElf(getpid(), true));
+  TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(ELFCLASS32, EM_ARM, true,
+                                               [&](uint64_t offset, const void* ptr, size_t size) {
+                                                 memory_->SetMemory(0x2000 + offset, ptr, size);
+                                               });
+
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, true));
   ASSERT_TRUE(elf.get() != nullptr);
   ASSERT_TRUE(elf->valid());
   EXPECT_EQ(static_cast<uint32_t>(EM_ARM), elf->machine_type());
@@ -130,12 +152,14 @@
 }
 
 TEST_F(MapInfoGetElfTest, gnu_debugdata_init64) {
-  TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(
-      ELFCLASS64, EM_AARCH64, true, [&](uint64_t offset, const void* ptr, size_t size) {
-        memcpy(&reinterpret_cast<uint8_t*>(map_)[offset], ptr, size);
-      });
+  MapInfo info{.start = 0x5000, .end = 0x8000, .offset = 0, .flags = PROT_READ, .name = ""};
 
-  std::unique_ptr<Elf> elf(info_->GetElf(getpid(), true));
+  TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(ELFCLASS64, EM_AARCH64, true,
+                                               [&](uint64_t offset, const void* ptr, size_t size) {
+                                                 memory_->SetMemory(0x5000 + offset, ptr, size);
+                                               });
+
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, true));
   ASSERT_TRUE(elf.get() != nullptr);
   ASSERT_TRUE(elf->valid());
   EXPECT_EQ(static_cast<uint32_t>(EM_AARCH64), elf->machine_type());
@@ -143,4 +167,195 @@
   EXPECT_TRUE(elf->gnu_debugdata_interface() != nullptr);
 }
 
+TEST_F(MapInfoGetElfTest, end_le_start) {
+  MapInfo info{.start = 0x1000, .end = 0x1000, .offset = 0, .flags = PROT_READ, .name = elf_.path};
+
+  Elf32_Ehdr ehdr;
+  TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
+  ASSERT_TRUE(android::base::WriteFully(elf_.fd, &ehdr, sizeof(ehdr)));
+
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, false));
+  ASSERT_FALSE(elf->valid());
+
+  info.elf = nullptr;
+  info.end = 0xfff;
+  elf.reset(info.GetElf(process_memory_, false));
+  ASSERT_FALSE(elf->valid());
+
+  // Make sure this test is valid.
+  info.elf = nullptr;
+  info.end = 0x2000;
+  elf.reset(info.GetElf(process_memory_, false));
+  ASSERT_TRUE(elf->valid());
+}
+
+// Verify that if the offset is non-zero but there is no elf at the offset,
+// that the full file is used.
+TEST_F(MapInfoGetElfTest, file_backed_non_zero_offset_full_file) {
+  MapInfo info{
+      .start = 0x1000, .end = 0x2000, .offset = 0x100, .flags = PROT_READ, .name = elf_.path};
+
+  std::vector<uint8_t> buffer(0x1000);
+  memset(buffer.data(), 0, buffer.size());
+  Elf32_Ehdr ehdr;
+  TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
+  memcpy(buffer.data(), &ehdr, sizeof(ehdr));
+  ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), buffer.size()));
+
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, false));
+  ASSERT_TRUE(elf->valid());
+  ASSERT_TRUE(elf->memory() != nullptr);
+  ASSERT_EQ(0x100U, info.elf_offset);
+
+  // Read the entire file.
+  memset(buffer.data(), 0, buffer.size());
+  ASSERT_TRUE(elf->memory()->Read(0, buffer.data(), buffer.size()));
+  ASSERT_EQ(0, memcmp(buffer.data(), &ehdr, sizeof(ehdr)));
+  for (size_t i = sizeof(ehdr); i < buffer.size(); i++) {
+    ASSERT_EQ(0, buffer[i]) << "Failed at byte " << i;
+  }
+
+  ASSERT_FALSE(elf->memory()->Read(buffer.size(), buffer.data(), 1));
+}
+
+// Verify that if the offset is non-zero and there is an elf at that
+// offset, that only part of the file is used.
+TEST_F(MapInfoGetElfTest, file_backed_non_zero_offset_partial_file) {
+  MapInfo info{
+      .start = 0x1000, .end = 0x2000, .offset = 0x2000, .flags = PROT_READ, .name = elf_.path};
+
+  std::vector<uint8_t> buffer(0x4000);
+  memset(buffer.data(), 0, buffer.size());
+  Elf32_Ehdr ehdr;
+  TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
+  memcpy(&buffer[info.offset], &ehdr, sizeof(ehdr));
+  ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), buffer.size()));
+
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, false));
+  ASSERT_TRUE(elf->valid());
+  ASSERT_TRUE(elf->memory() != nullptr);
+  ASSERT_EQ(0U, info.elf_offset);
+
+  // Read the valid part of the file.
+  ASSERT_TRUE(elf->memory()->Read(0, buffer.data(), 0x1000));
+  ASSERT_EQ(0, memcmp(buffer.data(), &ehdr, sizeof(ehdr)));
+  for (size_t i = sizeof(ehdr); i < 0x1000; i++) {
+    ASSERT_EQ(0, buffer[i]) << "Failed at byte " << i;
+  }
+
+  ASSERT_FALSE(elf->memory()->Read(0x1000, buffer.data(), 1));
+}
+
+// Verify that if the offset is non-zero and there is an elf at that
+// offset, that only part of the file is used. Further verify that if the
+// embedded elf is bigger than the initial map, the new object is larger
+// than the original map size. Do this for a 32 bit elf and a 64 bit elf.
+TEST_F(MapInfoGetElfTest, file_backed_non_zero_offset_partial_file_whole_elf32) {
+  MapInfo info{
+      .start = 0x5000, .end = 0x6000, .offset = 0x1000, .flags = PROT_READ, .name = elf_.path};
+
+  std::vector<uint8_t> buffer(0x4000);
+  memset(buffer.data(), 0, buffer.size());
+  Elf32_Ehdr ehdr;
+  TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, EM_ARM);
+  ehdr.e_shoff = 0x2000;
+  ehdr.e_shentsize = sizeof(Elf32_Shdr) + 100;
+  ehdr.e_shnum = 4;
+  memcpy(&buffer[info.offset], &ehdr, sizeof(ehdr));
+  ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), buffer.size()));
+
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, false));
+  ASSERT_TRUE(elf->valid());
+  ASSERT_TRUE(elf->memory() != nullptr);
+  ASSERT_EQ(0U, info.elf_offset);
+
+  // Verify the memory is a valid elf.
+  memset(buffer.data(), 0, buffer.size());
+  ASSERT_TRUE(elf->memory()->Read(0, buffer.data(), 0x1000));
+  ASSERT_EQ(0, memcmp(buffer.data(), &ehdr, sizeof(ehdr)));
+
+  // Read past the end of what would normally be the size of the map.
+  ASSERT_TRUE(elf->memory()->Read(0x1000, buffer.data(), 1));
+}
+
+TEST_F(MapInfoGetElfTest, file_backed_non_zero_offset_partial_file_whole_elf64) {
+  MapInfo info{
+      .start = 0x7000, .end = 0x8000, .offset = 0x1000, .flags = PROT_READ, .name = elf_.path};
+
+  std::vector<uint8_t> buffer(0x4000);
+  memset(buffer.data(), 0, buffer.size());
+  Elf64_Ehdr ehdr;
+  TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, EM_AARCH64);
+  ehdr.e_shoff = 0x2000;
+  ehdr.e_shentsize = sizeof(Elf64_Shdr) + 100;
+  ehdr.e_shnum = 4;
+  memcpy(&buffer[info.offset], &ehdr, sizeof(ehdr));
+  ASSERT_TRUE(android::base::WriteFully(elf_.fd, buffer.data(), buffer.size()));
+
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, false));
+  ASSERT_TRUE(elf->valid());
+  ASSERT_TRUE(elf->memory() != nullptr);
+  ASSERT_EQ(0U, info.elf_offset);
+
+  // Verify the memory is a valid elf.
+  memset(buffer.data(), 0, buffer.size());
+  ASSERT_TRUE(elf->memory()->Read(0, buffer.data(), 0x1000));
+  ASSERT_EQ(0, memcmp(buffer.data(), &ehdr, sizeof(ehdr)));
+
+  // Read past the end of what would normally be the size of the map.
+  ASSERT_TRUE(elf->memory()->Read(0x1000, buffer.data(), 1));
+}
+
+TEST_F(MapInfoGetElfTest, process_memory_not_read_only) {
+  MapInfo info{.start = 0x9000, .end = 0xa000, .offset = 0x1000, .flags = 0, .name = ""};
+
+  // Create valid elf data in process memory only.
+  Elf64_Ehdr ehdr;
+  TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, EM_AARCH64);
+  ehdr.e_shoff = 0x2000;
+  ehdr.e_shentsize = sizeof(Elf64_Shdr) + 100;
+  ehdr.e_shnum = 4;
+  memory_->SetMemory(0x9000, &ehdr, sizeof(ehdr));
+
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, false));
+  ASSERT_FALSE(elf->valid());
+
+  info.elf = nullptr;
+  info.flags = PROT_READ;
+  elf.reset(info.GetElf(process_memory_, false));
+  ASSERT_TRUE(elf->valid());
+}
+
+TEST_F(MapInfoGetElfTest, check_device_maps) {
+  MapInfo info{.start = 0x7000,
+               .end = 0x8000,
+               .offset = 0x1000,
+               .flags = PROT_READ | MAPS_FLAGS_DEVICE_MAP,
+               .name = "/dev/something"};
+
+  // Create valid elf data in process memory for this to verify that only
+  // the name is causing invalid elf data.
+  Elf64_Ehdr ehdr;
+  TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, EM_X86_64);
+  ehdr.e_shoff = 0x2000;
+  ehdr.e_shentsize = sizeof(Elf64_Shdr) + 100;
+  ehdr.e_shnum = 4;
+  memory_->SetMemory(0x7000, &ehdr, sizeof(ehdr));
+
+  std::unique_ptr<Elf> elf(info.GetElf(process_memory_, false));
+  ASSERT_FALSE(elf->valid());
+
+  // Set the name to nothing to verify that it still fails.
+  info.elf = nullptr;
+  info.name = "";
+  elf.reset(info.GetElf(process_memory_, false));
+  ASSERT_FALSE(elf->valid());
+
+  // Change the flags and verify the elf is valid now.
+  info.elf = nullptr;
+  info.flags = PROT_READ;
+  elf.reset(info.GetElf(process_memory_, false));
+  ASSERT_TRUE(elf->valid());
+}
+
 }  // namespace unwindstack
diff --git a/libunwindstack/tests/MemoryRangeTest.cpp b/libunwindstack/tests/MemoryRangeTest.cpp
index 6d1366c..680fae9 100644
--- a/libunwindstack/tests/MemoryRangeTest.cpp
+++ b/libunwindstack/tests/MemoryRangeTest.cpp
@@ -31,10 +31,11 @@
 TEST(MemoryRangeTest, read) {
   std::vector<uint8_t> src(1024);
   memset(src.data(), 0x4c, 1024);
-  MemoryFake* memory = new MemoryFake;
-  memory->SetMemory(9001, src);
+  MemoryFake* memory_fake = new MemoryFake;
+  std::shared_ptr<Memory> process_memory(memory_fake);
+  memory_fake->SetMemory(9001, src);
 
-  MemoryRange range(memory, 9001, 9001 + src.size());
+  MemoryRange range(process_memory, 9001, 9001 + src.size());
 
   std::vector<uint8_t> dst(1024);
   ASSERT_TRUE(range.Read(0, dst.data(), src.size()));
@@ -46,10 +47,11 @@
 TEST(MemoryRangeTest, read_near_limit) {
   std::vector<uint8_t> src(4096);
   memset(src.data(), 0x4c, 4096);
-  MemoryFake* memory = new MemoryFake;
-  memory->SetMemory(1000, src);
+  MemoryFake* memory_fake = new MemoryFake;
+  std::shared_ptr<Memory> process_memory(memory_fake);
+  memory_fake->SetMemory(1000, src);
 
-  MemoryRange range(memory, 1000, 2024);
+  MemoryRange range(process_memory, 1000, 2024);
 
   std::vector<uint8_t> dst(1024);
   ASSERT_TRUE(range.Read(1020, dst.data(), 4));
@@ -69,7 +71,8 @@
 TEST(MemoryRangeTest, read_overflow) {
   std::vector<uint8_t> buffer(100);
 
-  std::unique_ptr<MemoryRange> overflow(new MemoryRange(new MemoryFakeAlwaysReadZero, 100, 200));
+  std::shared_ptr<Memory> process_memory(new MemoryFakeAlwaysReadZero);
+  std::unique_ptr<MemoryRange> overflow(new MemoryRange(process_memory, 100, 200));
   ASSERT_FALSE(overflow->Read(UINT64_MAX - 10, buffer.data(), 100));
 }
 
diff --git a/libunwindstack/tests/UnwindTest.cpp b/libunwindstack/tests/UnwindTest.cpp
index 2fc3a38..a0c45bd 100644
--- a/libunwindstack/tests/UnwindTest.cpp
+++ b/libunwindstack/tests/UnwindTest.cpp
@@ -85,10 +85,11 @@
          function_names[index] + "\n" + "Unwind data:\n" + unwind_stream.str();
 }
 
-static void VerifyUnwind(pid_t pid, Memory* memory, Maps* maps, Regs* regs,
+static void VerifyUnwind(pid_t pid, Maps* maps, Regs* regs,
                          std::vector<const char*>& function_names) {
   size_t function_name_index = 0;
 
+  auto process_memory = Memory::CreateProcessMemory(pid);
   std::stringstream unwind_stream;
   unwind_stream << std::hex;
   for (size_t frame_num = 0; frame_num < 64; frame_num++) {
@@ -96,7 +97,7 @@
     MapInfo* map_info = maps->Find(regs->pc());
     ASSERT_TRUE(map_info != nullptr) << ErrorMsg(function_names, function_name_index, unwind_stream);
 
-    Elf* elf = map_info->GetElf(pid, true);
+    Elf* elf = map_info->GetElf(process_memory, true);
     uint64_t rel_pc = elf->GetRelPc(regs->pc(), map_info);
     uint64_t adjusted_rel_pc = rel_pc;
     if (frame_num != 0) {
@@ -122,7 +123,7 @@
       unwind_stream << " " << name;
     }
     unwind_stream << "\n";
-    ASSERT_TRUE(elf->Step(rel_pc + map_info->elf_offset, regs, memory))
+    ASSERT_TRUE(elf->Step(rel_pc + map_info->elf_offset, regs, process_memory.get()))
         << ErrorMsg(function_names, function_name_index, unwind_stream);
   }
   ASSERT_TRUE(false) << ErrorMsg(function_names, function_name_index, unwind_stream);
@@ -137,9 +138,8 @@
     ASSERT_TRUE(maps.Parse());
     std::unique_ptr<Regs> regs(Regs::CreateFromLocal());
     RegsGetLocal(regs.get());
-    MemoryLocal memory;
 
-    VerifyUnwind(getpid(), &memory, &maps, regs.get(), kFunctionOrder);
+    VerifyUnwind(getpid(), &maps, regs.get(), kFunctionOrder);
   } else {
     g_ready_for_remote = true;
     g_ready = true;
@@ -205,11 +205,10 @@
 
   RemoteMaps maps(pid);
   ASSERT_TRUE(maps.Parse());
-  MemoryRemote memory(pid);
   std::unique_ptr<Regs> regs(Regs::RemoteGet(pid));
   ASSERT_TRUE(regs.get() != nullptr);
 
-  VerifyUnwind(pid, &memory, &maps, regs.get(), kFunctionOrder);
+  VerifyUnwind(pid, &maps, regs.get(), kFunctionOrder);
 
   ASSERT_EQ(0, ptrace(PTRACE_DETACH, pid, 0, 0));
 
@@ -254,9 +253,8 @@
   LocalMaps maps;
   ASSERT_TRUE(maps.Parse());
   std::unique_ptr<Regs> regs(Regs::CreateFromUcontext(Regs::CurrentMachineType(), ucontext));
-  MemoryLocal memory;
 
-  VerifyUnwind(tid.load(), &memory, &maps, regs.get(), kFunctionOrder);
+  VerifyUnwind(getpid(), &maps, regs.get(), kFunctionOrder);
 
   ASSERT_EQ(0, sigaction(SIGUSR1, &oldact, nullptr));
 
@@ -291,11 +289,10 @@
 
   RemoteMaps maps(pid);
   ASSERT_TRUE(maps.Parse());
-  MemoryRemote memory(pid);
   std::unique_ptr<Regs> regs(Regs::RemoteGet(pid));
   ASSERT_TRUE(regs.get() != nullptr);
 
-  VerifyUnwind(pid, &memory, &maps, regs.get(), kFunctionSignalOrder);
+  VerifyUnwind(pid, &maps, regs.get(), kFunctionSignalOrder);
 
   ASSERT_EQ(0, ptrace(PTRACE_DETACH, pid, 0, 0));
 
diff --git a/libunwindstack/tools/unwind.cpp b/libunwindstack/tools/unwind.cpp
index c1077f8..3614198 100644
--- a/libunwindstack/tools/unwind.cpp
+++ b/libunwindstack/tools/unwind.cpp
@@ -91,7 +91,7 @@
   }
   printf("\n");
 
-  unwindstack::MemoryRemote remote_memory(pid);
+  auto process_memory = unwindstack::Memory::CreateProcessMemory(pid);
   for (size_t frame_num = 0; frame_num < 64; frame_num++) {
     if (regs->pc() == 0) {
       break;
@@ -102,7 +102,7 @@
       break;
     }
 
-    unwindstack::Elf* elf = map_info->GetElf(pid, true);
+    unwindstack::Elf* elf = map_info->GetElf(process_memory, true);
 
     uint64_t rel_pc = elf->GetRelPc(regs->pc(), map_info);
     uint64_t adjusted_rel_pc = rel_pc;
@@ -135,7 +135,7 @@
     }
     printf("\n");
 
-    if (!elf->Step(rel_pc + map_info->elf_offset, regs, &remote_memory)) {
+    if (!elf->Step(rel_pc + map_info->elf_offset, regs, process_memory.get())) {
       break;
     }
   }
diff --git a/libutils/SystemClock.cpp b/libutils/SystemClock.cpp
index 28fc351..73ec1be 100644
--- a/libutils/SystemClock.cpp
+++ b/libutils/SystemClock.cpp
@@ -23,9 +23,9 @@
 
 #include <utils/SystemClock.h>
 
-#include <sys/time.h>
 #include <string.h>
 #include <errno.h>
+#include <time.h>
 
 #include <cutils/compiler.h>