Merge "Remove liblog/uio.c and <log/uio.h>"
diff --git a/adb/client/adb_install.cpp b/adb/client/adb_install.cpp
index 0d0375d..21e0874 100644
--- a/adb/client/adb_install.cpp
+++ b/adb/client/adb_install.cpp
@@ -500,17 +500,22 @@
 int install_multi_package(int argc, const char** argv) {
     // Find all APK arguments starting at end.
     // All other arguments passed through verbatim.
-    int first_apk = -1;
+    bool apex_found = false;
+    int first_package = -1;
     for (int i = argc - 1; i >= 0; i--) {
         const char* file = argv[i];
-        if (android::base::EndsWithIgnoreCase(file, ".apk")) {
-            first_apk = i;
+        if (android::base::EndsWithIgnoreCase(file, ".apk") ||
+            android::base::EndsWithIgnoreCase(file, ".apex")) {
+            first_package = i;
+            if (android::base::EndsWithIgnoreCase(file, ".apex")) {
+                apex_found = true;
+            }
         } else {
             break;
         }
     }
 
-    if (first_apk == -1) error_exit("need APK file on command line");
+    if (first_package == -1) error_exit("need APK or APEX files on command line");
 
     if (use_legacy_install()) {
         fprintf(stderr, "adb: multi-package install is not supported on this device\n");
@@ -520,6 +525,9 @@
 
     std::string multi_package_cmd =
             android::base::StringPrintf("%s install-create --multi-package", install_cmd.c_str());
+    if (apex_found) {
+        multi_package_cmd += " --staged";
+    }
 
     // Create multi-package install session
     std::string error;
@@ -557,15 +565,25 @@
     std::string individual_cmd =
             android::base::StringPrintf("%s install-create", install_cmd.c_str());
     std::string all_session_ids = "";
-    for (int i = 1; i < first_apk; i++) {
+    for (int i = 1; i < first_package; i++) {
         individual_cmd += " " + escape_arg(argv[i]);
     }
+    if (apex_found) {
+        individual_cmd += " --staged";
+    }
+    std::string individual_apex_cmd = individual_cmd + " --apex";
     std::string cmd = "";
-    for (int i = first_apk; i < argc; i++) {
-        // Create individual install session
+    for (int i = first_package; i < argc; i++) {
+        const char* file = argv[i];
         char buf[BUFSIZ];
         {
-            unique_fd fd(adb_connect(individual_cmd, &error));
+            unique_fd fd;
+            // Create individual install session
+            if (android::base::EndsWithIgnoreCase(file, ".apex")) {
+                fd.reset(adb_connect(individual_apex_cmd, &error));
+            } else {
+                fd.reset(adb_connect(individual_cmd, &error));
+            }
             if (fd < 0) {
                 fprintf(stderr, "adb: connect error for create: %s\n", error.c_str());
                 goto finalize_multi_package_session;
@@ -591,7 +609,6 @@
         fprintf(stdout, "Created child session ID %d.\n", session_id);
         session_ids.push_back(session_id);
 
-        const char* file = argv[i];
         struct stat sb;
         if (stat(file, &sb) == -1) {
             fprintf(stderr, "adb: failed to stat %s: %s\n", file, strerror(errno));
@@ -633,7 +650,7 @@
     {
         unique_fd fd(adb_connect(cmd, &error));
         if (fd < 0) {
-            fprintf(stderr, "adb: connect error for create: %s\n", error.c_str());
+            fprintf(stderr, "adb: connect error for install-add-session: %s\n", error.c_str());
             goto finalize_multi_package_session;
         }
         read_status_line(fd.get(), buf, sizeof(buf));
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 785f9a2..19445c8 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -556,9 +556,17 @@
     mkdir(target.c_str(), 0755);
     errno = 0;
     unsigned long mountflags = entry.flags;
-    int ret = mount(source.c_str(), target.c_str(), entry.fs_type.c_str(), mountflags,
+    int ret = 0;
+    int save_errno = 0;
+    do {
+        if (save_errno == EAGAIN) {
+            PINFO << "Retrying mount (source=" << source << ",target=" << target
+                  << ",type=" << entry.fs_type << ")=" << ret << "(" << save_errno << ")";
+        }
+        ret = mount(source.c_str(), target.c_str(), entry.fs_type.c_str(), mountflags,
                     entry.fs_options.c_str());
-    int save_errno = errno;
+        save_errno = errno;
+    } while (ret && save_errno == EAGAIN);
     const char* target_missing = "";
     const char* source_missing = "";
     if (save_errno == ENOENT) {
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 45dc6d3..008a868 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -103,13 +103,17 @@
         int st;
         if (IsF2Fs()) {
             const char* f2fs_argv[] = {
-                "/system/bin/fsck.f2fs", "-f", mnt_fsname_.c_str(),
+                    "/system/bin/fsck.f2fs",
+                    "-a",
+                    mnt_fsname_.c_str(),
             };
             android_fork_execvp_ext(arraysize(f2fs_argv), (char**)f2fs_argv, &st, true, LOG_KLOG,
                                     true, nullptr, nullptr, 0);
         } else if (IsExt4()) {
             const char* ext4_argv[] = {
-                "/system/bin/e2fsck", "-f", "-y", mnt_fsname_.c_str(),
+                    "/system/bin/e2fsck",
+                    "-y",
+                    mnt_fsname_.c_str(),
             };
             android_fork_execvp_ext(arraysize(ext4_argv), (char**)ext4_argv, &st, true, LOG_KLOG,
                                     true, nullptr, nullptr, 0);
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 58d88df..4fd36f5 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -19,7 +19,6 @@
     "config_write.cpp",
     "log_event_list.cpp",
     "log_event_write.cpp",
-    "log_ratelimit.cpp",
     "logger_lock.cpp",
     "logger_name.cpp",
     "logger_read.cpp",
diff --git a/liblog/include/log/log.h b/liblog/include/log/log.h
index 6f93396..5928649 100644
--- a/liblog/include/log/log.h
+++ b/liblog/include/log/log.h
@@ -164,33 +164,6 @@
  */
 void __android_log_close(void);
 
-/*
- * if last is NULL, caller _must_ provide a consistent value for seconds.
- *
- * Return -1 if we can not acquire a lock, which below will permit the logging,
- * error on allowing a log message through.
- */
-int __android_log_ratelimit(time_t seconds, time_t* last);
-
-/*
- * Usage:
- *
- *   // Global default and state
- *   IF_ALOG_RATELIMIT() {
- *      ALOG*(...);
- *   }
- *
- *   // local state, 10 seconds ratelimit
- *   static time_t local_state;
- *   IF_ALOG_RATELIMIT_LOCAL(10, &local_state) {
- *     ALOG*(...);
- *   }
- */
-
-#define IF_ALOG_RATELIMIT() if (__android_log_ratelimit(0, NULL) > 0)
-#define IF_ALOG_RATELIMIT_LOCAL(seconds, state) \
-  if (__android_log_ratelimit(seconds, state) > 0)
-
 #if defined(__clang__)
 #pragma clang diagnostic pop
 #endif
diff --git a/liblog/include/log/log_event_list.h b/liblog/include/log/log_event_list.h
index b376504..636d417 100644
--- a/liblog/include/log/log_event_list.h
+++ b/liblog/include/log/log_event_list.h
@@ -109,8 +109,6 @@
 /* android_log_list C++ helpers */
 extern "C++" {
 class android_log_event_list {
-  friend class __android_log_event_list;
-
  private:
   android_log_context ctx;
   int ret;
@@ -122,10 +120,6 @@
   explicit android_log_event_list(int tag) : ret(0) {
     ctx = create_android_logger(static_cast<uint32_t>(tag));
   }
-  explicit android_log_event_list(log_msg& log_msg) : ret(0) {
-    ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
-                                    log_msg.entry.len - sizeof(uint32_t));
-  }
   ~android_log_event_list() {
     android_log_destroy(&ctx);
   }
@@ -283,13 +277,6 @@
     if (retval < 0) ret = retval;
     return ret >= 0;
   }
-
-  android_log_list_element read() {
-    return android_log_read_next(ctx);
-  }
-  android_log_list_element peek() {
-    return android_log_peek_next(ctx);
-  }
 };
 }
 #endif
diff --git a/liblog/include/log/log_time.h b/liblog/include/log/log_time.h
index be69255..09c9910 100644
--- a/liblog/include/log/log_time.h
+++ b/liblog/include/log/log_time.h
@@ -42,23 +42,19 @@
  */
 struct log_time {
  public:
-  uint32_t tv_sec; /* good to Feb 5 2106 */
-  uint32_t tv_nsec;
+  uint32_t tv_sec = 0; /* good to Feb 5 2106 */
+  uint32_t tv_nsec = 0;
 
   static const uint32_t tv_sec_max = 0xFFFFFFFFUL;
   static const uint32_t tv_nsec_max = 999999999UL;
+  static const timespec EPOCH;
 
-  log_time(const timespec& T)
-      : tv_sec(static_cast<uint32_t>(T.tv_sec)),
-        tv_nsec(static_cast<uint32_t>(T.tv_nsec)) {
-  }
+  log_time() {}
+  explicit log_time(const timespec& T)
+      : tv_sec(static_cast<uint32_t>(T.tv_sec)), tv_nsec(static_cast<uint32_t>(T.tv_nsec)) {}
   explicit log_time(uint32_t sec, uint32_t nsec = 0)
       : tv_sec(sec), tv_nsec(nsec) {
   }
-#define __struct_log_time_private_defined
-  static const timespec EPOCH;
-  log_time() {
-  }
 #ifdef __linux__
   explicit log_time(clockid_t id) {
     timespec T;
diff --git a/liblog/include/private/android_logger.h b/liblog/include/private/android_logger.h
index 830f651..5e04148 100644
--- a/liblog/include/private/android_logger.h
+++ b/liblog/include/private/android_logger.h
@@ -150,37 +150,6 @@
 /* Retrieve the composed event buffer */
 int android_log_write_list_buffer(android_log_context ctx, const char** msg);
 
-#ifdef __cplusplus
-#ifdef __class_android_log_event_list_defined
-#ifndef __class_android_log_event_list_private_defined
-#define __class_android_log_event_list_private_defined
-/* android_log_context C++ helpers */
-extern "C++" {
-class __android_log_event_list : public android_log_event_list {
-  __android_log_event_list(const android_log_event_list&) = delete;
-  void operator=(const __android_log_event_list&) = delete;
-
- public:
-  explicit __android_log_event_list(int tag) : android_log_event_list(tag) {
-  }
-  explicit __android_log_event_list(log_msg& log_msg)
-      : android_log_event_list(log_msg) {
-  }
-
-  operator std::string() {
-    if (ret) return std::string("");
-    const char* cp = nullptr;
-    ssize_t len = android_log_write_list_buffer(ctx, &cp);
-    if (len < 0) ret = len;
-    if (!cp || (len <= 0)) return std::string("");
-    return std::string(cp, len);
-  }
-};
-}
-#endif
-#endif
-#endif
-
 #if defined(__cplusplus)
 }
 #endif
diff --git a/liblog/log_ratelimit.cpp b/liblog/log_ratelimit.cpp
deleted file mode 100644
index 33770dd..0000000
--- a/liblog/log_ratelimit.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-** Copyright 2016, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include <errno.h>
-#include <pthread.h>
-#include <time.h>
-
-#include <log/log.h>
-
-#include "log_portability.h"
-
-// Global default if 'last' argument in __android_log_ratelimit is NULL
-static time_t g_last_clock;
-// Global above can not deal well with callers playing games with the
-// seconds argument, so we will also hold on to the maximum value
-// ever provided and use that to gain consistency.  If the caller
-// provides their own 'last' argument, then they can play such games
-// of varying the 'seconds' argument to their pleasure.
-static time_t g_last_seconds;
-static const time_t last_seconds_default = 10;
-static const time_t last_seconds_max = 24 * 60 * 60;  // maximum of a day
-static const time_t last_seconds_min = 2;             // granularity
-// Lock to protect last_clock and last_seconds, but also 'last'
-// argument (not NULL) as supplied to __android_log_ratelimit.
-static pthread_mutex_t lock_ratelimit = PTHREAD_MUTEX_INITIALIZER;
-
-// if last is NULL, caller _must_ provide a consistent value for
-// seconds, otherwise we will take the maximum ever issued and hold
-// on to that.  Preserves value of non-zero errno.  Return -1 if we
-// can not acquire a lock, 0 if we are not to log a message, and 1
-// if we are ok to log a message.  Caller should check > 0 for true.
-LIBLOG_ABI_PUBLIC int __android_log_ratelimit(time_t seconds, time_t* last) {
-  int save_errno = errno;
-
-  // Two reasons for trylock failure:
-  //   1. In a signal handler. Must prevent deadlock
-  //   2. Too many threads calling __android_log_ratelimit.
-  //      Bonus to not print if they race here because that
-  //      dovetails the goal of ratelimiting. One may print
-  //      and the others will wait their turn ...
-  if (pthread_mutex_trylock(&lock_ratelimit)) {
-    if (save_errno) errno = save_errno;
-    return -1;
-  }
-
-  if (seconds == 0) {
-    seconds = last_seconds_default;
-  } else if (seconds < last_seconds_min) {
-    seconds = last_seconds_min;
-  } else if (seconds > last_seconds_max) {
-    seconds = last_seconds_max;
-  }
-
-  if (!last) {
-    if (g_last_seconds > seconds) {
-      seconds = g_last_seconds;
-    } else if (g_last_seconds < seconds) {
-      g_last_seconds = seconds;
-    }
-    last = &g_last_clock;
-  }
-
-  time_t now = time(NULL);
-  if ((now == (time_t)-1) || ((*last + seconds) > now)) {
-    pthread_mutex_unlock(&lock_ratelimit);
-    if (save_errno) errno = save_errno;
-    return 0;
-  }
-  *last = now;
-  pthread_mutex_unlock(&lock_ratelimit);
-  if (save_errno) errno = save_errno;
-  return 1;
-}
diff --git a/liblog/log_time.cpp b/liblog/log_time.cpp
index ae376be..77bb94f 100644
--- a/liblog/log_time.cpp
+++ b/liblog/log_time.cpp
@@ -137,7 +137,7 @@
 LIBLOG_ABI_PRIVATE log_time log_time::operator-=(const timespec& T) {
   // No concept of negative time, clamp to EPOCH
   if (*this <= T) {
-    return *this = EPOCH;
+    return *this = log_time(EPOCH);
   }
 
   if (this->tv_nsec < (unsigned long int)T.tv_nsec) {
@@ -165,7 +165,7 @@
 LIBLOG_ABI_PRIVATE log_time log_time::operator-=(const log_time& T) {
   // No concept of negative time, clamp to EPOCH
   if (*this <= T) {
-    return *this = EPOCH;
+    return *this = log_time(EPOCH);
   }
 
   if (this->tv_nsec < T.tv_nsec) {
diff --git a/liblog/tests/Android.bp b/liblog/tests/Android.bp
index 2c47fd6..4ab2acb 100644
--- a/liblog/tests/Android.bp
+++ b/liblog/tests/Android.bp
@@ -29,10 +29,10 @@
         "-fno-builtin",
     ],
     shared_libs: [
-        "liblog",
         "libm",
         "libbase",
     ],
+    static_libs: ["liblog"],
     srcs: ["liblog_benchmark.cpp"],
 }
 
@@ -63,10 +63,10 @@
         "log_wrap_test.cpp",
     ],
     shared_libs: [
-        "liblog",
         "libcutils",
         "libbase",
     ],
+    static_libs: ["liblog"],
 }
 
 // Build tests for the device (with .so). Run with:
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 2d0fc9b..83f0fa9 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -3160,41 +3160,6 @@
 }
 #endif  // USING_LOGGER_DEFAULT
 
-#ifdef USING_LOGGER_DEFAULT  // Do not retest ratelimit
-TEST(liblog, __android_log_ratelimit) {
-  time_t state = 0;
-
-  errno = 42;
-  // Prime
-  __android_log_ratelimit(3, &state);
-  EXPECT_EQ(errno, 42);
-  // Check
-  EXPECT_FALSE(__android_log_ratelimit(3, &state));
-  sleep(1);
-  EXPECT_FALSE(__android_log_ratelimit(3, &state));
-  sleep(4);
-  EXPECT_TRUE(__android_log_ratelimit(3, &state));
-  sleep(5);
-  EXPECT_TRUE(__android_log_ratelimit(3, &state));
-
-  // API checks
-  IF_ALOG_RATELIMIT_LOCAL(3, &state) {
-    EXPECT_FALSE(0 != "IF_ALOG_RATELIMIT_LOCAL(3, &state)");
-  }
-
-  IF_ALOG_RATELIMIT() {
-    ;
-  }
-  else {
-    EXPECT_TRUE(0 == "IF_ALOG_RATELIMIT()");
-  }
-  IF_ALOG_RATELIMIT() {
-    EXPECT_FALSE(0 != "IF_ALOG_RATELIMIT()");
-  }
-  // Do not test default seconds, to allow liblog to tune freely
-}
-#endif  // USING_LOGGER_DEFAULT
-
 #ifdef USING_LOGGER_DEFAULT  // Do not retest event mapping functionality
 TEST(liblog, android_lookupEventTagNum) {
 #ifdef __ANDROID__
diff --git a/libnativeloader/Android.bp b/libnativeloader/Android.bp
index 8903b72..2802d36 100644
--- a/libnativeloader/Android.bp
+++ b/libnativeloader/Android.bp
@@ -23,15 +23,6 @@
         "llndk.libraries.txt",
         "vndksp.libraries.txt",
     ],
-    target: {
-        android: {
-            version_script: "libnativeloader.map.txt",
-        },
-    },
-    stubs: {
-        symbol_file: "libnativeloader.map.txt",
-        versions: ["1"],
-    },
 }
 
 cc_library_headers {
diff --git a/libnativeloader/OWNERS b/libnativeloader/OWNERS
index 5c28a9f..f735653 100644
--- a/libnativeloader/OWNERS
+++ b/libnativeloader/OWNERS
@@ -1,2 +1,6 @@
 dimitry@google.com
 jiyong@google.com
+ngeoffray@google.com
+oth@google.com
+mast@google.com
+rpl@google.com
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index f231afa..af7df72 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -632,7 +632,7 @@
     *needs_native_bridge = false;
     void* handle = dlopen(path, RTLD_NOW);
     if (handle == nullptr) {
-      *error_msg = dlerror();
+      *error_msg = strdup(dlerror());
     }
     return handle;
   }
diff --git a/libstats/include/stats_event_list.h b/libstats/include/stats_event_list.h
index 162d1cf..b5bc5af 100644
--- a/libstats/include/stats_event_list.h
+++ b/libstats/include/stats_event_list.h
@@ -51,10 +51,6 @@
     explicit stats_event_list(int tag) : ret(0) {
         ctx = create_android_logger(static_cast<uint32_t>(tag));
     }
-    explicit stats_event_list(log_msg& log_msg) : ret(0) {
-        ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
-                                        log_msg.entry.len - sizeof(uint32_t));
-    }
     ~stats_event_list() { android_log_destroy(&ctx); }
 
     int close() {
@@ -251,9 +247,6 @@
         }
         return ret >= 0;
     }
-
-    android_log_list_element read() { return android_log_read_next(ctx); }
-    android_log_list_element peek() { return android_log_peek_next(ctx); }
 };
 
 #endif
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index e267f58..73dc921 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -127,6 +127,10 @@
         },
     },
 
+    whole_static_libs: [
+        "libdemangle"
+    ],
+
     static_libs: [
         "libprocinfo",
     ],
@@ -189,6 +193,7 @@
         "tests/MapInfoCreateMemoryTest.cpp",
         "tests/MapInfoGetElfTest.cpp",
         "tests/MapInfoGetLoadBiasTest.cpp",
+        "tests/MapInfoTest.cpp",
         "tests/MapsTest.cpp",
         "tests/MemoryBufferTest.cpp",
         "tests/MemoryCacheTest.cpp",
diff --git a/libunwindstack/MapInfo.cpp b/libunwindstack/MapInfo.cpp
index 39a09cf..b9d8b3d 100644
--- a/libunwindstack/MapInfo.cpp
+++ b/libunwindstack/MapInfo.cpp
@@ -221,6 +221,19 @@
   return elf.get();
 }
 
+bool MapInfo::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) {
+  {
+    // Make sure no other thread is trying to update this elf object.
+    std::lock_guard<std::mutex> guard(mutex_);
+    if (elf == nullptr) {
+      return false;
+    }
+  }
+  // No longer need the lock, once the elf object is created, it is not deleted
+  // until this object is deleted.
+  return elf->GetFunctionName(addr, name, func_offset);
+}
+
 uint64_t MapInfo::GetLoadBias(const std::shared_ptr<Memory>& process_memory) {
   uint64_t cur_load_bias = load_bias.load();
   if (cur_load_bias != static_cast<uint64_t>(-1)) {
diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp
index 8133639..57207de 100644
--- a/libunwindstack/Unwinder.cpp
+++ b/libunwindstack/Unwinder.cpp
@@ -26,10 +26,13 @@
 
 #include <android-base/stringprintf.h>
 
+#include <demangle.h>
+
 #include <unwindstack/Elf.h>
 #include <unwindstack/JitDebug.h>
 #include <unwindstack/MapInfo.h>
 #include <unwindstack/Maps.h>
+#include <unwindstack/Memory.h>
 #include <unwindstack/Unwinder.h>
 
 #if !defined(NO_LIBDEXFILE_SUPPORT)
@@ -306,7 +309,7 @@
   }
 
   if (!frame.function_name.empty()) {
-    data += " (" + frame.function_name;
+    data += " (" + demangle(frame.function_name.c_str());
     if (frame.function_offset != 0) {
       data += android::base::StringPrintf("+%" PRId64, frame.function_offset);
     }
@@ -327,4 +330,29 @@
 }
 #endif
 
+bool UnwinderFromPid::Init(ArchEnum arch) {
+  if (pid_ == getpid()) {
+    maps_ptr_.reset(new LocalMaps());
+  } else {
+    maps_ptr_.reset(new RemoteMaps(pid_));
+  }
+  if (!maps_ptr_->Parse()) {
+    return false;
+  }
+  maps_ = maps_ptr_.get();
+
+  process_memory_ = Memory::CreateProcessMemoryCached(pid_);
+
+  jit_debug_ptr_.reset(new JitDebug(process_memory_));
+  jit_debug_ = jit_debug_ptr_.get();
+  SetJitDebug(jit_debug_, arch);
+#if !defined(NO_LIBDEXFILE_SUPPORT)
+  dex_files_ptr_.reset(new DexFiles(process_memory_));
+  dex_files_ = dex_files_ptr_.get();
+  SetDexFiles(dex_files_, arch);
+#endif
+
+  return true;
+}
+
 }  // namespace unwindstack
diff --git a/libunwindstack/include/unwindstack/MapInfo.h b/libunwindstack/include/unwindstack/MapInfo.h
index 5e3d6f6..a9febd1 100644
--- a/libunwindstack/include/unwindstack/MapInfo.h
+++ b/libunwindstack/include/unwindstack/MapInfo.h
@@ -75,6 +75,8 @@
 
   Memory* CreateMemory(const std::shared_ptr<Memory>& process_memory);
 
+  bool GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset);
+
  private:
   MapInfo(const MapInfo&) = delete;
   void operator=(const MapInfo&) = delete;
diff --git a/libunwindstack/include/unwindstack/Unwinder.h b/libunwindstack/include/unwindstack/Unwinder.h
index d7bbd9d..ab239c1 100644
--- a/libunwindstack/include/unwindstack/Unwinder.h
+++ b/libunwindstack/include/unwindstack/Unwinder.h
@@ -24,7 +24,9 @@
 #include <string>
 #include <vector>
 
+#include <unwindstack/DexFiles.h>
 #include <unwindstack/Error.h>
+#include <unwindstack/JitDebug.h>
 #include <unwindstack/Maps.h>
 #include <unwindstack/Memory.h>
 #include <unwindstack/Regs.h>
@@ -32,9 +34,7 @@
 namespace unwindstack {
 
 // Forward declarations.
-class DexFiles;
 class Elf;
-class JitDebug;
 enum ArchEnum : uint8_t;
 
 struct FrameData {
@@ -67,6 +67,11 @@
       : max_frames_(max_frames), maps_(maps), regs_(regs), process_memory_(process_memory) {
     frames_.reserve(max_frames);
   }
+  Unwinder(size_t max_frames, Maps* maps, std::shared_ptr<Memory> process_memory)
+      : max_frames_(max_frames), maps_(maps), process_memory_(process_memory) {
+    frames_.reserve(max_frames);
+  }
+
   ~Unwinder() = default;
 
   void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr,
@@ -81,6 +86,10 @@
 
   void SetJitDebug(JitDebug* jit_debug, ArchEnum arch);
 
+  void SetRegs(Regs* regs) { regs_ = regs; }
+  Maps* GetMaps() { return maps_; }
+  std::shared_ptr<Memory>& GetProcessMemory() { return process_memory_; }
+
   // Disabling the resolving of names results in the function name being
   // set to an empty string and the function offset being set to zero.
   void SetResolveNames(bool resolve) { resolve_names_ = resolve; }
@@ -92,7 +101,9 @@
   ErrorCode LastErrorCode() { return last_error_.code; }
   uint64_t LastErrorAddress() { return last_error_.address; }
 
- private:
+ protected:
+  Unwinder(size_t max_frames) : max_frames_(max_frames) { frames_.reserve(max_frames); }
+
   void FillInDexFrame();
   void FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, uint64_t func_pc,
                    uint64_t pc_adjustment);
@@ -110,6 +121,22 @@
   ErrorData last_error_;
 };
 
+class UnwinderFromPid : public Unwinder {
+ public:
+  UnwinderFromPid(size_t max_frames, pid_t pid) : Unwinder(max_frames), pid_(pid) {}
+  ~UnwinderFromPid() = default;
+
+  bool Init(ArchEnum arch);
+
+ private:
+  pid_t pid_;
+  std::unique_ptr<Maps> maps_ptr_;
+  std::unique_ptr<JitDebug> jit_debug_ptr_;
+#if !defined(NO_LIBDEXFILE_SUPPORT)
+  std::unique_ptr<DexFiles> dex_files_ptr_;
+#endif
+};
+
 }  // namespace unwindstack
 
 #endif  // _LIBUNWINDSTACK_UNWINDER_H
diff --git a/libunwindstack/tests/MapInfoTest.cpp b/libunwindstack/tests/MapInfoTest.cpp
new file mode 100644
index 0000000..e2cbb98
--- /dev/null
+++ b/libunwindstack/tests/MapInfoTest.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+
+#include <gtest/gtest.h>
+
+#include <unwindstack/MapInfo.h>
+#include <unwindstack/Maps.h>
+
+#include "ElfFake.h"
+
+namespace unwindstack {
+
+TEST(MapInfoTest, maps_constructor_const_char) {
+  MapInfo prev_map(nullptr, 0, 0, 0, 0, "");
+  MapInfo map_info(&prev_map, 1, 2, 3, 4, "map");
+
+  EXPECT_EQ(&prev_map, map_info.prev_map);
+  EXPECT_EQ(1UL, map_info.start);
+  EXPECT_EQ(2UL, map_info.end);
+  EXPECT_EQ(3UL, map_info.offset);
+  EXPECT_EQ(4UL, map_info.flags);
+  EXPECT_EQ("map", map_info.name);
+  EXPECT_EQ(static_cast<uint64_t>(-1), map_info.load_bias);
+  EXPECT_EQ(0UL, map_info.elf_offset);
+  EXPECT_TRUE(map_info.elf.get() == nullptr);
+}
+
+TEST(MapInfoTest, maps_constructor_string) {
+  std::string name("string_map");
+  MapInfo prev_map(nullptr, 0, 0, 0, 0, "");
+  MapInfo map_info(&prev_map, 1, 2, 3, 4, name);
+
+  EXPECT_EQ(&prev_map, map_info.prev_map);
+  EXPECT_EQ(1UL, map_info.start);
+  EXPECT_EQ(2UL, map_info.end);
+  EXPECT_EQ(3UL, map_info.offset);
+  EXPECT_EQ(4UL, map_info.flags);
+  EXPECT_EQ("string_map", map_info.name);
+  EXPECT_EQ(static_cast<uint64_t>(-1), map_info.load_bias);
+  EXPECT_EQ(0UL, map_info.elf_offset);
+  EXPECT_TRUE(map_info.elf.get() == nullptr);
+}
+
+TEST(MapInfoTest, get_function_name) {
+  ElfFake* elf = new ElfFake(nullptr);
+  ElfInterfaceFake* interface = new ElfInterfaceFake(nullptr);
+  elf->FakeSetInterface(interface);
+  interface->FakePushFunctionData(FunctionData("function", 1000));
+
+  MapInfo map_info(nullptr, 1, 2, 3, 4, "");
+  map_info.elf.reset(elf);
+
+  std::string name;
+  uint64_t offset;
+  ASSERT_TRUE(map_info.GetFunctionName(1000, &name, &offset));
+  EXPECT_EQ("function", name);
+  EXPECT_EQ(1000UL, offset);
+}
+
+}  // namespace unwindstack
diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp
index aab9ec2..0588a84 100644
--- a/libunwindstack/tests/UnwindOfflineTest.cpp
+++ b/libunwindstack/tests/UnwindOfflineTest.cpp
@@ -210,8 +210,8 @@
   ASSERT_EQ(4U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
   EXPECT_EQ(
       "  #00 pc 0001a9f8  libc.so (abort+64)\n"
-      "  #01 pc 00006a1b  libbase.so (_ZN7android4base14DefaultAborterEPKc+6)\n"
-      "  #02 pc 00007441  libbase.so (_ZN7android4base10LogMessageD2Ev+748)\n"
+      "  #01 pc 00006a1b  libbase.so (android::base::DefaultAborter(char const*)+6)\n"
+      "  #02 pc 00007441  libbase.so (android::base::LogMessage::~LogMessage()+748)\n"
       "  #03 pc 00015147  /does/not/exist/libhidlbase.so\n",
       frame_info);
   EXPECT_EQ(0xf31ea9f8U, unwinder.frames()[0].pc);
@@ -234,9 +234,10 @@
   ASSERT_EQ(2U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
   EXPECT_EQ(
       "  #00 pc 0006dc49  libandroid_runtime.so "
-      "(_ZN7android14AndroidRuntime15javaThreadShellEPv+80)\n"
+      "(android::AndroidRuntime::javaThreadShell(void*)+80)\n"
       "  #01 pc 0006dce5  libandroid_runtime.so "
-      "(_ZN7android14AndroidRuntime19javaCreateThreadEtcEPFiPvES1_PKcijPS1_)\n",
+      "(android::AndroidRuntime::javaCreateThreadEtc(int (*)(void*), void*, char const*, int, "
+      "unsigned int, void**))\n",
       frame_info);
   EXPECT_EQ(0xf1f6dc49U, unwinder.frames()[0].pc);
   EXPECT_EQ(0xd8fe6930U, unwinder.frames()[0].sp);
@@ -257,10 +258,10 @@
       "  #01 pc 000000000042a078  libunwindstack_test (SignalMiddleFunction+8)\n"
       "  #02 pc 000000000042a08c  libunwindstack_test (SignalOuterFunction+8)\n"
       "  #03 pc 000000000042d8fc  libunwindstack_test "
-      "(_ZN11unwindstackL19RemoteThroughSignalEij+20)\n"
+      "(unwindstack::RemoteThroughSignal(int, unsigned int)+20)\n"
       "  #04 pc 000000000042d8d8  libunwindstack_test "
-      "(_ZN11unwindstack37UnwindTest_remote_through_signal_Test8TestBodyEv+32)\n"
-      "  #05 pc 0000000000455d70  libunwindstack_test (_ZN7testing4Test3RunEv+392)\n",
+      "(unwindstack::UnwindTest_remote_through_signal_Test::TestBody()+32)\n"
+      "  #05 pc 0000000000455d70  libunwindstack_test (testing::Test::Run()+392)\n",
       frame_info);
   EXPECT_EQ(0x64d09d4fd8U, unwinder.frames()[0].pc);
   EXPECT_EQ(0x7fe0d84040U, unwinder.frames()[0].sp);
@@ -296,54 +297,57 @@
   std::string frame_info(DumpFrames(unwinder));
   ASSERT_EQ(69U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
   EXPECT_EQ(
-      "  #00 pc 00068fb8  libarttestd.so (_ZN3artL13CauseSegfaultEv+72)\n"
+      "  #00 pc 00068fb8  libarttestd.so (art::CauseSegfault()+72)\n"
       "  #01 pc 00067f00  libarttestd.so (Java_Main_unwindInProcess+10032)\n"
       "  #02 pc 000021a8  137-cfi.odex (offset 0x2000) (boolean Main.unwindInProcess(boolean, int, "
       "boolean)+136)\n"
       "  #03 pc 0000fe80  anonymous:ee74c000 (boolean Main.bar(boolean)+64)\n"
       "  #04 pc 006ad4d2  libartd.so (art_quick_invoke_stub+338)\n"
       "  #05 pc 00146ab5  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+885)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+885)\n"
       "  #06 pc 0039cf0d  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+653)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+653)\n"
       "  #07 pc 00392552  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+354)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+354)\n"
       "  #08 pc 0039399a  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+234)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+234)\n"
       "  #09 pc 00684362  libartd.so (artQuickToInterpreterBridge+1058)\n"
       "  #10 pc 006b35bd  libartd.so (art_quick_to_interpreter_bridge+77)\n"
       "  #11 pc 0000fe03  anonymous:ee74c000 (int Main.compare(Main, Main)+51)\n"
       "  #12 pc 006ad4d2  libartd.so (art_quick_invoke_stub+338)\n"
       "  #13 pc 00146ab5  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+885)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+885)\n"
       "  #14 pc 0039cf0d  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+653)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+653)\n"
       "  #15 pc 00392552  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+354)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+354)\n"
       "  #16 pc 0039399a  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+234)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+234)\n"
       "  #17 pc 00684362  libartd.so (artQuickToInterpreterBridge+1058)\n"
       "  #18 pc 006b35bd  libartd.so (art_quick_to_interpreter_bridge+77)\n"
       "  #19 pc 0000fd3b  anonymous:ee74c000 (int Main.compare(java.lang.Object, "
       "java.lang.Object)+107)\n"
       "  #20 pc 006ad4d2  libartd.so (art_quick_invoke_stub+338)\n"
       "  #21 pc 00146ab5  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+885)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+885)\n"
       "  #22 pc 0039cf0d  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+653)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+653)\n"
       "  #23 pc 00392552  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+354)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+354)\n"
       "  #24 pc 0039399a  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+234)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+234)\n"
       "  #25 pc 00684362  libartd.so (artQuickToInterpreterBridge+1058)\n"
       "  #26 pc 006b35bd  libartd.so (art_quick_to_interpreter_bridge+77)\n"
       "  #27 pc 0000fbdb  anonymous:ee74c000 (int "
@@ -351,81 +355,86 @@
       "java.util.Comparator)+331)\n"
       "  #28 pc 006ad6a2  libartd.so (art_quick_invoke_static_stub+418)\n"
       "  #29 pc 00146acb  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+907)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+907)\n"
       "  #30 pc 0039cf0d  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+653)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+653)\n"
       "  #31 pc 00392552  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+354)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+354)\n"
       "  #32 pc 0039399a  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+234)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+234)\n"
       "  #33 pc 00684362  libartd.so (artQuickToInterpreterBridge+1058)\n"
       "  #34 pc 006b35bd  libartd.so (art_quick_to_interpreter_bridge+77)\n"
       "  #35 pc 0000f624  anonymous:ee74c000 (boolean Main.foo()+164)\n"
       "  #36 pc 006ad4d2  libartd.so (art_quick_invoke_stub+338)\n"
       "  #37 pc 00146ab5  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+885)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+885)\n"
       "  #38 pc 0039cf0d  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+653)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+653)\n"
       "  #39 pc 00392552  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+354)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+354)\n"
       "  #40 pc 0039399a  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+234)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+234)\n"
       "  #41 pc 00684362  libartd.so (artQuickToInterpreterBridge+1058)\n"
       "  #42 pc 006b35bd  libartd.so (art_quick_to_interpreter_bridge+77)\n"
       "  #43 pc 0000eedb  anonymous:ee74c000 (void Main.runPrimary()+59)\n"
       "  #44 pc 006ad4d2  libartd.so (art_quick_invoke_stub+338)\n"
       "  #45 pc 00146ab5  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+885)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+885)\n"
       "  #46 pc 0039cf0d  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+653)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+653)\n"
       "  #47 pc 00392552  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+354)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+354)\n"
       "  #48 pc 0039399a  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+234)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+234)\n"
       "  #49 pc 00684362  libartd.so (artQuickToInterpreterBridge+1058)\n"
       "  #50 pc 006b35bd  libartd.so (art_quick_to_interpreter_bridge+77)\n"
       "  #51 pc 0000ac21  anonymous:ee74c000 (void Main.main(java.lang.String[])+97)\n"
       "  #52 pc 006ad6a2  libartd.so (art_quick_invoke_static_stub+418)\n"
       "  #53 pc 00146acb  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+907)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+907)\n"
       "  #54 pc 0039cf0d  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+653)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+653)\n"
       "  #55 pc 00392552  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+354)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+354)\n"
       "  #56 pc 0039399a  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+234)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+234)\n"
       "  #57 pc 00684362  libartd.so (artQuickToInterpreterBridge+1058)\n"
       "  #58 pc 006b35bd  libartd.so (art_quick_to_interpreter_bridge+77)\n"
       "  #59 pc 006ad6a2  libartd.so (art_quick_invoke_static_stub+418)\n"
       "  #60 pc 00146acb  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+907)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+907)\n"
       "  #61 pc 005aac95  libartd.so "
-      "(_ZN3artL18InvokeWithArgArrayERKNS_33ScopedObjectAccessAlreadyRunnableEPNS_9ArtMethodEPNS_"
-      "8ArgArrayEPNS_6JValueEPKc+85)\n"
+      "(art::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, "
+      "art::ArgArray*, art::JValue*, char const*)+85)\n"
       "  #62 pc 005aab5a  libartd.so "
-      "(_ZN3art17InvokeWithVarArgsERKNS_33ScopedObjectAccessAlreadyRunnableEP8_jobjectP10_"
-      "jmethodIDPc+362)\n"
+      "(art::InvokeWithVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, "
+      "_jmethodID*, char*)+362)\n"
       "  #63 pc 0048a3dd  libartd.so "
-      "(_ZN3art3JNI21CallStaticVoidMethodVEP7_JNIEnvP7_jclassP10_jmethodIDPc+125)\n"
+      "(art::JNI::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, char*)+125)\n"
       "  #64 pc 0018448c  libartd.so "
-      "(_ZN3art8CheckJNI11CallMethodVEPKcP7_JNIEnvP8_jobjectP7_jclassP10_jmethodIDPcNS_"
-      "9Primitive4TypeENS_10InvokeTypeE+1964)\n"
+      "(art::CheckJNI::CallMethodV(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, char*, "
+      "art::Primitive::Type, art::InvokeType)+1964)\n"
       "  #65 pc 0017cf06  libartd.so "
-      "(_ZN3art8CheckJNI21CallStaticVoidMethodVEP7_JNIEnvP7_jclassP10_jmethodIDPc+70)\n"
+      "(art::CheckJNI::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, char*)+70)\n"
       "  #66 pc 00001d8c  dalvikvm32 "
-      "(_ZN7_JNIEnv20CallStaticVoidMethodEP7_jclassP10_jmethodIDz+60)\n"
+      "(_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)+60)\n"
       "  #67 pc 00001a80  dalvikvm32 (main+1312)\n"
       "  #68 pc 00018275  libc.so\n",
       frame_info);
@@ -597,32 +606,34 @@
       "  #03 pc 00462175  libartd.so (art_quick_invoke_stub_internal+68)\n"
       "  #04 pc 00467129  libartd.so (art_quick_invoke_stub+228)\n"
       "  #05 pc 000bf7a9  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+864)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+864)\n"
       "  #06 pc 00247833  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+382)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+382)\n"
       "  #07 pc 0022e935  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+244)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+244)\n"
       "  #08 pc 0022f71d  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+128)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+128)\n"
       "  #09 pc 00442865  libartd.so (artQuickToInterpreterBridge+796)\n"
       "  #10 pc 004666ff  libartd.so (art_quick_to_interpreter_bridge+30)\n"
       "  #11 pc 00011c31  anonymous:e2796000 (int Main.compare(Main, Main)+64)\n"
       "  #12 pc 00462175  libartd.so (art_quick_invoke_stub_internal+68)\n"
       "  #13 pc 00467129  libartd.so (art_quick_invoke_stub+228)\n"
       "  #14 pc 000bf7a9  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+864)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+864)\n"
       "  #15 pc 00247833  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+382)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+382)\n"
       "  #16 pc 0022e935  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+244)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+244)\n"
       "  #17 pc 0022f71d  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+128)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+128)\n"
       "  #18 pc 00442865  libartd.so (artQuickToInterpreterBridge+796)\n"
       "  #19 pc 004666ff  libartd.so (art_quick_to_interpreter_bridge+30)\n"
       "  #20 pc 00011b77  anonymous:e2796000 (int Main.compare(java.lang.Object, "
@@ -630,16 +641,17 @@
       "  #21 pc 00462175  libartd.so (art_quick_invoke_stub_internal+68)\n"
       "  #22 pc 00467129  libartd.so (art_quick_invoke_stub+228)\n"
       "  #23 pc 000bf7a9  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+864)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+864)\n"
       "  #24 pc 00247833  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+382)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+382)\n"
       "  #25 pc 0022e935  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+244)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+244)\n"
       "  #26 pc 0022f71d  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+128)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+128)\n"
       "  #27 pc 00442865  libartd.so (artQuickToInterpreterBridge+796)\n"
       "  #28 pc 004666ff  libartd.so (art_quick_to_interpreter_bridge+30)\n"
       "  #29 pc 00011a29  anonymous:e2796000 (int "
@@ -648,85 +660,90 @@
       "  #30 pc 00462175  libartd.so (art_quick_invoke_stub_internal+68)\n"
       "  #31 pc 0046722f  libartd.so (art_quick_invoke_static_stub+226)\n"
       "  #32 pc 000bf7bb  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+882)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+882)\n"
       "  #33 pc 00247833  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+382)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+382)\n"
       "  #34 pc 0022e935  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+244)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+244)\n"
       "  #35 pc 0022f71d  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+128)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+128)\n"
       "  #36 pc 00442865  libartd.so (artQuickToInterpreterBridge+796)\n"
       "  #37 pc 004666ff  libartd.so (art_quick_to_interpreter_bridge+30)\n"
       "  #38 pc 0001139b  anonymous:e2796000 (boolean Main.foo()+178)\n"
       "  #39 pc 00462175  libartd.so (art_quick_invoke_stub_internal+68)\n"
       "  #40 pc 00467129  libartd.so (art_quick_invoke_stub+228)\n"
       "  #41 pc 000bf7a9  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+864)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+864)\n"
       "  #42 pc 00247833  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+382)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+382)\n"
       "  #43 pc 0022e935  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+244)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+244)\n"
       "  #44 pc 0022f71d  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+128)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+128)\n"
       "  #45 pc 00442865  libartd.so (artQuickToInterpreterBridge+796)\n"
       "  #46 pc 004666ff  libartd.so (art_quick_to_interpreter_bridge+30)\n"
       "  #47 pc 00010aa7  anonymous:e2796000 (void Main.runPrimary()+70)\n"
       "  #48 pc 00462175  libartd.so (art_quick_invoke_stub_internal+68)\n"
       "  #49 pc 00467129  libartd.so (art_quick_invoke_stub+228)\n"
       "  #50 pc 000bf7a9  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+864)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+864)\n"
       "  #51 pc 00247833  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+382)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+382)\n"
       "  #52 pc 0022e935  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+244)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+244)\n"
       "  #53 pc 0022f71d  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+128)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+128)\n"
       "  #54 pc 00442865  libartd.so (artQuickToInterpreterBridge+796)\n"
       "  #55 pc 004666ff  libartd.so (art_quick_to_interpreter_bridge+30)\n"
       "  #56 pc 0000ba99  anonymous:e2796000 (void Main.main(java.lang.String[])+144)\n"
       "  #57 pc 00462175  libartd.so (art_quick_invoke_stub_internal+68)\n"
       "  #58 pc 0046722f  libartd.so (art_quick_invoke_static_stub+226)\n"
       "  #59 pc 000bf7bb  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+882)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+882)\n"
       "  #60 pc 00247833  libartd.so "
-      "(_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPNS_"
-      "11ShadowFrameEtPNS_6JValueE+382)\n"
+      "(art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, "
+      "art::ShadowFrame*, unsigned short, art::JValue*)+382)\n"
       "  #61 pc 0022e935  libartd.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+244)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+244)\n"
       "  #62 pc 0022f71d  libartd.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+128)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+128)\n"
       "  #63 pc 00442865  libartd.so (artQuickToInterpreterBridge+796)\n"
       "  #64 pc 004666ff  libartd.so (art_quick_to_interpreter_bridge+30)\n"
       "  #65 pc 00462175  libartd.so (art_quick_invoke_stub_internal+68)\n"
       "  #66 pc 0046722f  libartd.so (art_quick_invoke_static_stub+226)\n"
       "  #67 pc 000bf7bb  libartd.so "
-      "(_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+882)\n"
+      "(art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char "
+      "const*)+882)\n"
       "  #68 pc 003b292d  libartd.so "
-      "(_ZN3artL18InvokeWithArgArrayERKNS_33ScopedObjectAccessAlreadyRunnableEPNS_9ArtMethodEPNS_"
-      "8ArgArrayEPNS_6JValueEPKc+52)\n"
+      "(art::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, "
+      "art::ArgArray*, art::JValue*, char const*)+52)\n"
       "  #69 pc 003b26c3  libartd.so "
-      "(_ZN3art17InvokeWithVarArgsERKNS_33ScopedObjectAccessAlreadyRunnableEP8_jobjectP10_"
-      "jmethodIDSt9__va_list+210)\n"
+      "(art::InvokeWithVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, "
+      "_jmethodID*, std::__va_list)+210)\n"
       "  #70 pc 00308411  libartd.so "
-      "(_ZN3art3JNI21CallStaticVoidMethodVEP7_JNIEnvP7_jclassP10_jmethodIDSt9__va_list+76)\n"
+      "(art::JNI::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+76)\n"
       "  #71 pc 000e6a9f  libartd.so "
-      "(_ZN3art8CheckJNI11CallMethodVEPKcP7_JNIEnvP8_jobjectP7_jclassP10_jmethodIDSt9__va_listNS_"
-      "9Primitive4TypeENS_10InvokeTypeE+1486)\n"
+      "(art::CheckJNI::CallMethodV(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, "
+      "std::__va_list, art::Primitive::Type, art::InvokeType)+1486)\n"
       "  #72 pc 000e19b9  libartd.so "
-      "(_ZN3art8CheckJNI21CallStaticVoidMethodVEP7_JNIEnvP7_jclassP10_jmethodIDSt9__va_list+40)\n"
+      "(art::CheckJNI::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+40)\n"
       "  #73 pc 0000159f  dalvikvm32 "
-      "(_ZN7_JNIEnv20CallStaticVoidMethodEP7_jclassP10_jmethodIDz+30)\n"
+      "(_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)+30)\n"
       "  #74 pc 00001349  dalvikvm32 (main+896)\n"
       "  #75 pc 000850c9  libc.so\n",
       frame_info);
@@ -997,41 +1014,44 @@
       "(com.example.simpleperf.simpleperfexamplewithnative.MixActivity$1.run+60)\n"
       "  #02 pc 004135bb  libart.so (art_quick_osr_stub+42)\n"
       "  #03 pc 002657a5  libart.so "
-      "(_ZN3art3jit3Jit25MaybeDoOnStackReplacementEPNS_6ThreadEPNS_9ArtMethodEjiPNS_6JValueE+876)\n"
+      "(art::jit::Jit::MaybeDoOnStackReplacement(art::Thread*, art::ArtMethod*, unsigned int, int, "
+      "art::JValue*)+876)\n"
       "  #04 pc 004021a7  libart.so (MterpMaybeDoOnStackReplacement+86)\n"
       "  #05 pc 00412474  libart.so (ExecuteMterpImpl+66164)\n"
       "  #06 pc cd8365b0  <unknown>\n"  // symbol in dex file
       "  #07 pc 001d7f1b  libart.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+374)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+374)\n"
       "  #08 pc 001dc593  libart.so "
-      "(_ZN3art11interpreter33ArtInterpreterToInterpreterBridgeEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameEPNS_6JValueE+154)\n"
+      "(art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, "
+      "art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*)+154)\n"
       "  #09 pc 001f4d01  libart.so "
-      "(_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_"
-      "11InstructionEtPNS_6JValueE+732)\n"
+      "(bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, "
+      "art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+732)\n"
       "  #10 pc 003fe427  libart.so (MterpInvokeInterface+1354)\n"
       "  #11 pc 00405b94  libart.so (ExecuteMterpImpl+14740)\n"
       "  #12 pc 7004873e  <unknown>\n"  // symbol in dex file
       "  #13 pc 001d7f1b  libart.so "
-      "(_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_"
-      "6JValueEb+374)\n"
+      "(art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, "
+      "art::ShadowFrame&, art::JValue, bool)+374)\n"
       "  #14 pc 001dc4d5  libart.so "
-      "(_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadERKNS_"
-      "20CodeItemDataAccessorEPNS_11ShadowFrameE+92)\n"
+      "(art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::CodeItemDataAccessor "
+      "const&, art::ShadowFrame*)+92)\n"
       "  #15 pc 003f25ab  libart.so (artQuickToInterpreterBridge+970)\n"
       "  #16 pc 00417aff  libart.so (art_quick_to_interpreter_bridge+30)\n"
       "  #17 pc 00413575  libart.so (art_quick_invoke_stub_internal+68)\n"
       "  #18 pc 00418531  libart.so (art_quick_invoke_stub+236)\n"
-      "  #19 pc 000b468d  libart.so (_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+136)\n"
+      "  #19 pc 000b468d  libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned "
+      "int, art::JValue*, char const*)+136)\n"
       "  #20 pc 00362f49  libart.so "
-      "(_ZN3art12_GLOBAL__N_118InvokeWithArgArrayERKNS_33ScopedObjectAccessAlreadyRunnableEPNS_"
-      "9ArtMethodEPNS0_8ArgArrayEPNS_6JValueEPKc+52)\n"
+      "(art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable "
+      "const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char "
+      "const*)+52)\n"
       "  #21 pc 00363cd9  libart.so "
-      "(_ZN3art35InvokeVirtualOrInterfaceWithJValuesERKNS_33ScopedObjectAccessAlreadyRunnableEP8_"
-      "jobjectP10_jmethodIDP6jvalue+332)\n"
-      "  #22 pc 003851dd  libart.so (_ZN3art6Thread14CreateCallbackEPv+868)\n"
-      "  #23 pc 00062925  libc.so (_ZL15__pthread_startPv+22)\n"
+      "(art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, "
+      "_jobject*, _jmethodID*, jvalue*)+332)\n"
+      "  #22 pc 003851dd  libart.so (art::Thread::CreateCallback(void*)+868)\n"
+      "  #23 pc 00062925  libc.so (__pthread_start(void*)+22)\n"
       "  #24 pc 0001de39  libc.so (__start_thread+24)\n",
       frame_info);
   EXPECT_EQ(0xd025c788U, unwinder.frames()[0].pc);
@@ -1107,8 +1127,8 @@
       "(com.example.simpleperf.simpleperfexamplewithnative.MixActivity$1.run+60)\n"
       "  #02 pc 004135bb  libart.so (art_quick_osr_stub+42)\n"
 
-      "  #03 pc 003851dd  libart.so (_ZN3art6Thread14CreateCallbackEPv+868)\n"
-      "  #04 pc 00062925  libc.so (_ZL15__pthread_startPv+22)\n"
+      "  #03 pc 003851dd  libart.so (art::Thread::CreateCallback(void*)+868)\n"
+      "  #04 pc 00062925  libc.so (__pthread_start(void*)+22)\n"
       "  #05 pc 0001de39  libc.so (__start_thread+24)\n",
       frame_info);
 
@@ -1139,22 +1159,22 @@
       "  #01 pc 0032bfeb  libunwindstack_test (SignalMiddleFunction+2)\n"
       "  #02 pc 0032bff3  libunwindstack_test (SignalOuterFunction+2)\n"
       "  #03 pc 0032fed3  libunwindstack_test "
-      "(_ZN11unwindstackL19SignalCallerHandlerEiP7siginfoPv+26)\n"
+      "(unwindstack::SignalCallerHandler(int, siginfo*, void*)+26)\n"
       "  #04 pc 00026528  libc.so\n"
       "  #05 pc 00000000  <unknown>\n"
       "  #06 pc 0032c2d9  libunwindstack_test (InnerFunction+736)\n"
       "  #07 pc 0032cc4f  libunwindstack_test (MiddleFunction+42)\n"
       "  #08 pc 0032cc81  libunwindstack_test (OuterFunction+42)\n"
       "  #09 pc 0032e547  libunwindstack_test "
-      "(_ZN11unwindstackL19RemoteThroughSignalEij+270)\n"
+      "(unwindstack::RemoteThroughSignal(int, unsigned int)+270)\n"
       "  #10 pc 0032ed99  libunwindstack_test "
-      "(_ZN11unwindstack55UnwindTest_remote_through_signal_with_invalid_func_Test8TestBodyEv+16)\n"
-      "  #11 pc 00354453  libunwindstack_test (_ZN7testing4Test3RunEv+154)\n"
-      "  #12 pc 00354de7  libunwindstack_test (_ZN7testing8TestInfo3RunEv+194)\n"
-      "  #13 pc 00355105  libunwindstack_test (_ZN7testing8TestCase3RunEv+180)\n"
+      "(unwindstack::UnwindTest_remote_through_signal_with_invalid_func_Test::TestBody()+16)\n"
+      "  #11 pc 00354453  libunwindstack_test (testing::Test::Run()+154)\n"
+      "  #12 pc 00354de7  libunwindstack_test (testing::TestInfo::Run()+194)\n"
+      "  #13 pc 00355105  libunwindstack_test (testing::TestCase::Run()+180)\n"
       "  #14 pc 0035a215  libunwindstack_test "
-      "(_ZN7testing8internal12UnitTestImpl11RunAllTestsEv+664)\n"
-      "  #15 pc 00359f4f  libunwindstack_test (_ZN7testing8UnitTest3RunEv+110)\n"
+      "(testing::internal::UnitTestImpl::RunAllTests()+664)\n"
+      "  #15 pc 00359f4f  libunwindstack_test (testing::UnitTest::Run()+110)\n"
       "  #16 pc 0034d3db  libunwindstack_test (main+38)\n"
       "  #17 pc 00092c0d  libc.so (__libc_init+48)\n"
       "  #18 pc 0004202f  libunwindstack_test (_start_main+38)\n",
@@ -1213,9 +1233,9 @@
   EXPECT_EQ(
       "  #00 pc 0005138c  libc.so (__ioctl+8)\n"
       "  #01 pc 0002140f  libc.so (ioctl+30)\n"
-      "  #02 pc 00039535  libbinder.so (_ZN7android14IPCThreadState14talkWithDriverEb+204)\n"
-      "  #03 pc 00039633  libbinder.so (_ZN7android14IPCThreadState20getAndExecuteCommandEv+10)\n"
-      "  #04 pc 00039b57  libbinder.so (_ZN7android14IPCThreadState14joinThreadPoolEb+38)\n"
+      "  #02 pc 00039535  libbinder.so (android::IPCThreadState::talkWithDriver(bool)+204)\n"
+      "  #03 pc 00039633  libbinder.so (android::IPCThreadState::getAndExecuteCommand()+10)\n"
+      "  #04 pc 00039b57  libbinder.so (android::IPCThreadState::joinThreadPool(bool)+38)\n"
       "  #05 pc 00000c21  mediaserver (main+104)\n"
       "  #06 pc 00084b89  libc.so (__libc_init+48)\n"
       "  #07 pc 00000b77  mediaserver (_start_main+38)\n",
diff --git a/libunwindstack/tests/UnwindTest.cpp b/libunwindstack/tests/UnwindTest.cpp
index ea992c7..a91bd95 100644
--- a/libunwindstack/tests/UnwindTest.cpp
+++ b/libunwindstack/tests/UnwindTest.cpp
@@ -44,6 +44,13 @@
 
 namespace unwindstack {
 
+enum TestTypeEnum : uint8_t {
+  TEST_TYPE_LOCAL_UNWINDER = 0,
+  TEST_TYPE_LOCAL_UNWINDER_FROM_PID,
+  TEST_TYPE_REMOTE,
+  TEST_TYPE_REMOTE_WITH_INVALID_CALL,
+};
+
 static std::atomic_bool g_ready;
 static volatile bool g_ready_for_remote;
 static volatile bool g_signal_ready_for_remote;
@@ -88,10 +95,10 @@
   SignalOuterFunction();
 }
 
-static std::string ErrorMsg(const std::vector<const char*>& function_names, Unwinder& unwinder) {
+static std::string ErrorMsg(const std::vector<const char*>& function_names, Unwinder* unwinder) {
   std::string unwind;
-  for (size_t i = 0; i < unwinder.NumFrames(); i++) {
-    unwind += unwinder.FormatFrame(i) + '\n';
+  for (size_t i = 0; i < unwinder->NumFrames(); i++) {
+    unwind += unwinder->FormatFrame(i) + '\n';
   }
 
   return std::string(
@@ -100,14 +107,10 @@
          function_names.front() + "\n" + "Unwind data:\n" + unwind;
 }
 
-static void VerifyUnwind(pid_t pid, Maps* maps, Regs* regs,
-                         std::vector<const char*> expected_function_names) {
-  auto process_memory(Memory::CreateProcessMemory(pid));
+static void VerifyUnwind(Unwinder* unwinder, std::vector<const char*> expected_function_names) {
+  unwinder->Unwind();
 
-  Unwinder unwinder(512, maps, regs, process_memory);
-  unwinder.Unwind();
-
-  for (auto& frame : unwinder.frames()) {
+  for (auto& frame : unwinder->frames()) {
     if (frame.function_name == expected_function_names.back()) {
       expected_function_names.pop_back();
       if (expected_function_names.empty()) {
@@ -119,35 +122,55 @@
   ASSERT_TRUE(expected_function_names.empty()) << ErrorMsg(expected_function_names, unwinder);
 }
 
+static void VerifyUnwind(pid_t pid, Maps* maps, Regs* regs,
+                         std::vector<const char*> expected_function_names) {
+  auto process_memory(Memory::CreateProcessMemory(pid));
+
+  Unwinder unwinder(512, maps, regs, process_memory);
+  VerifyUnwind(&unwinder, expected_function_names);
+}
+
 // This test assumes that this code is compiled with optimizations turned
 // off. If this doesn't happen, then all of the calls will be optimized
 // away.
-extern "C" void InnerFunction(bool local, bool trigger_invalid_call) {
-  if (local) {
-    LocalMaps maps;
-    ASSERT_TRUE(maps.Parse());
-    std::unique_ptr<Regs> regs(Regs::CreateFromLocal());
-    RegsGetLocal(regs.get());
-
-    VerifyUnwind(getpid(), &maps, regs.get(), kFunctionOrder);
-  } else {
+extern "C" void InnerFunction(TestTypeEnum test_type) {
+  if (test_type == TEST_TYPE_REMOTE || test_type == TEST_TYPE_REMOTE_WITH_INVALID_CALL) {
     g_ready_for_remote = true;
     g_ready = true;
-    if (trigger_invalid_call) {
+    if (test_type == TEST_TYPE_REMOTE_WITH_INVALID_CALL) {
       void (*crash_func)() = nullptr;
       crash_func();
     }
     while (!g_finish.load()) {
     }
+    return;
   }
+
+  std::unique_ptr<Unwinder> unwinder;
+  std::unique_ptr<Regs> regs(Regs::CreateFromLocal());
+  RegsGetLocal(regs.get());
+  std::unique_ptr<Maps> maps;
+
+  if (test_type == TEST_TYPE_LOCAL_UNWINDER) {
+    maps.reset(new LocalMaps());
+    ASSERT_TRUE(maps->Parse());
+    auto process_memory(Memory::CreateProcessMemory(getpid()));
+    unwinder.reset(new Unwinder(512, maps.get(), regs.get(), process_memory));
+  } else {
+    UnwinderFromPid* unwinder_from_pid = new UnwinderFromPid(512, getpid());
+    ASSERT_TRUE(unwinder_from_pid->Init(regs->Arch()));
+    unwinder_from_pid->SetRegs(regs.get());
+    unwinder.reset(unwinder_from_pid);
+  }
+  VerifyUnwind(unwinder.get(), kFunctionOrder);
 }
 
-extern "C" void MiddleFunction(bool local, bool trigger_invalid_call) {
-  InnerFunction(local, trigger_invalid_call);
+extern "C" void MiddleFunction(TestTypeEnum test_type) {
+  InnerFunction(test_type);
 }
 
-extern "C" void OuterFunction(bool local, bool trigger_invalid_call) {
-  MiddleFunction(local, trigger_invalid_call);
+extern "C" void OuterFunction(TestTypeEnum test_type) {
+  MiddleFunction(test_type);
 }
 
 class UnwindTest : public ::testing::Test {
@@ -156,7 +179,11 @@
 };
 
 TEST_F(UnwindTest, local) {
-  OuterFunction(true, false);
+  OuterFunction(TEST_TYPE_LOCAL_UNWINDER);
+}
+
+TEST_F(UnwindTest, local_use_from_pid) {
+  OuterFunction(TEST_TYPE_LOCAL_UNWINDER_FROM_PID);
 }
 
 void WaitForRemote(pid_t pid, uint64_t addr, bool leave_attached, bool* completed) {
@@ -191,7 +218,7 @@
 TEST_F(UnwindTest, remote) {
   pid_t pid;
   if ((pid = fork()) == 0) {
-    OuterFunction(false, false);
+    OuterFunction(TEST_TYPE_REMOTE);
     exit(0);
   }
   ASSERT_NE(-1, pid);
@@ -212,11 +239,39 @@
       << "ptrace detach failed with unexpected error: " << strerror(errno);
 }
 
+TEST_F(UnwindTest, unwind_from_pid_remote) {
+  pid_t pid;
+  if ((pid = fork()) == 0) {
+    OuterFunction(TEST_TYPE_REMOTE);
+    exit(0);
+  }
+  ASSERT_NE(-1, pid);
+  TestScopedPidReaper reap(pid);
+
+  bool completed;
+  WaitForRemote(pid, reinterpret_cast<uint64_t>(&g_ready_for_remote), true, &completed);
+  ASSERT_TRUE(completed) << "Timed out waiting for remote process to be ready.";
+
+  std::unique_ptr<Regs> regs(Regs::RemoteGet(pid));
+  ASSERT_TRUE(regs.get() != nullptr);
+
+  UnwinderFromPid unwinder(512, pid);
+  ASSERT_TRUE(unwinder.Init(regs->Arch()));
+  unwinder.SetRegs(regs.get());
+
+  VerifyUnwind(&unwinder, kFunctionOrder);
+
+  // Verify that calling the same object works again.
+
+  ASSERT_EQ(0, ptrace(PTRACE_DETACH, pid, 0, 0))
+      << "ptrace detach failed with unexpected error: " << strerror(errno);
+}
+
 TEST_F(UnwindTest, from_context) {
   std::atomic_int tid(0);
   std::thread thread([&]() {
     tid = syscall(__NR_gettid);
-    OuterFunction(false, false);
+    OuterFunction(TEST_TYPE_REMOTE);
   });
 
   struct sigaction act, oldact;
@@ -266,7 +321,7 @@
     act.sa_flags = SA_RESTART | SA_ONSTACK | sa_flags;
     ASSERT_EQ(0, sigaction(signal, &act, &oldact));
 
-    OuterFunction(false, signal == SIGSEGV);
+    OuterFunction(signal != SIGSEGV ? TEST_TYPE_REMOTE : TEST_TYPE_REMOTE_WITH_INVALID_CALL);
     exit(0);
   }
   ASSERT_NE(-1, pid);
diff --git a/libunwindstack/tests/UnwinderTest.cpp b/libunwindstack/tests/UnwinderTest.cpp
index 1fdeee5..49aeeb3 100644
--- a/libunwindstack/tests/UnwinderTest.cpp
+++ b/libunwindstack/tests/UnwinderTest.cpp
@@ -1080,6 +1080,12 @@
             Unwinder::FormatFrame(frame, false));
   EXPECT_EQ("  #01 pc 00001000  /fake/libfake.so (function)", Unwinder::FormatFrame(frame, true));
 
+  // Verify the function name is demangled.
+  frame.function_name = "_ZN4funcEv";
+  EXPECT_EQ("  #01 pc 0000000000001000  /fake/libfake.so (func())",
+            Unwinder::FormatFrame(frame, false));
+  EXPECT_EQ("  #01 pc 00001000  /fake/libfake.so (func())", Unwinder::FormatFrame(frame, true));
+
   frame.function_name = "";
   EXPECT_EQ("  #01 pc 0000000000001000  /fake/libfake.so", Unwinder::FormatFrame(frame, false));
   EXPECT_EQ("  #01 pc 00001000  /fake/libfake.so", Unwinder::FormatFrame(frame, true));
diff --git a/libunwindstack/tools/unwind.cpp b/libunwindstack/tools/unwind.cpp
index e729453..1812e50 100644
--- a/libunwindstack/tools/unwind.cpp
+++ b/libunwindstack/tools/unwind.cpp
@@ -57,12 +57,6 @@
 }
 
 void DoUnwind(pid_t pid) {
-  unwindstack::RemoteMaps remote_maps(pid);
-  if (!remote_maps.Parse()) {
-    printf("Failed to parse map data.\n");
-    return;
-  }
-
   unwindstack::Regs* regs = unwindstack::Regs::RemoteGet(pid);
   if (regs == nullptr) {
     printf("Unable to get remote reg data\n");
@@ -95,15 +89,13 @@
   }
   printf("\n");
 
-  auto process_memory = unwindstack::Memory::CreateProcessMemory(pid);
-  unwindstack::Unwinder unwinder(128, &remote_maps, regs, process_memory);
+  unwindstack::UnwinderFromPid unwinder(1024, pid);
+  if (!unwinder.Init(regs->Arch())) {
+    printf("Failed to init unwinder object.\n");
+    return;
+  }
 
-  unwindstack::JitDebug jit_debug(process_memory);
-  unwinder.SetJitDebug(&jit_debug, regs->Arch());
-
-  unwindstack::DexFiles dex_files(process_memory);
-  unwinder.SetDexFiles(&dex_files, regs->Arch());
-
+  unwinder.SetRegs(regs);
   unwinder.Unwind();
 
   // Print the frames.
diff --git a/libunwindstack/tools/unwind_for_offline.cpp b/libunwindstack/tools/unwind_for_offline.cpp
index 5ae8874..4f67d67 100644
--- a/libunwindstack/tools/unwind_for_offline.cpp
+++ b/libunwindstack/tools/unwind_for_offline.cpp
@@ -240,12 +240,6 @@
     return 1;
   }
 
-  unwindstack::RemoteMaps maps(pid);
-  if (!maps.Parse()) {
-    printf("Unable to parse maps.\n");
-    return 1;
-  }
-
   // Save the current state of the registers.
   if (!SaveRegs(regs)) {
     return 1;
@@ -253,35 +247,38 @@
 
   // Do an unwind so we know how much of the stack to save, and what
   // elf files are involved.
+  unwindstack::UnwinderFromPid unwinder(1024, pid);
+  if (!unwinder.Init(regs->Arch())) {
+    printf("Unable to init unwinder object.\n");
+    return 1;
+  }
+  unwinder.SetRegs(regs);
   uint64_t sp = regs->sp();
-  auto process_memory = unwindstack::Memory::CreateProcessMemory(pid);
-  unwindstack::JitDebug jit_debug(process_memory);
-  unwindstack::Unwinder unwinder(1024, &maps, regs, process_memory);
-  unwinder.SetJitDebug(&jit_debug, regs->Arch());
   unwinder.Unwind();
 
   std::unordered_map<uint64_t, map_info_t> maps_by_start;
   std::vector<std::pair<uint64_t, uint64_t>> stacks;
+  unwindstack::Maps* maps = unwinder.GetMaps();
   uint64_t sp_map_start = 0;
-  unwindstack::MapInfo* map_info = maps.Find(sp);
+  unwindstack::MapInfo* map_info = maps->Find(sp);
   if (map_info != nullptr) {
     stacks.emplace_back(std::make_pair(sp, map_info->end));
     sp_map_start = map_info->start;
   }
 
   for (const auto& frame : unwinder.frames()) {
-    map_info = maps.Find(frame.sp);
+    map_info = maps->Find(frame.sp);
     if (map_info != nullptr && sp_map_start != map_info->start) {
       stacks.emplace_back(std::make_pair(frame.sp, map_info->end));
       sp_map_start = map_info->start;
     }
 
     if (maps_by_start.count(frame.map_start) == 0) {
-      map_info = maps.Find(frame.map_start);
+      map_info = maps->Find(frame.map_start);
 
       auto info = FillInAndGetMapInfo(maps_by_start, map_info);
       bool file_copied = false;
-      SaveMapInformation(process_memory, info, &file_copied);
+      SaveMapInformation(unwinder.GetProcessMemory(), info, &file_copied);
 
       // If you are using a a linker that creates two maps (one read-only, one
       // read-executable), it's necessary to capture the previous map
@@ -291,7 +288,7 @@
           prev_map->flags == PROT_READ && map_info->name == prev_map->name &&
           maps_by_start.count(prev_map->start) == 0) {
         info = FillInAndGetMapInfo(maps_by_start, prev_map);
-        SaveMapInformation(process_memory, info, &file_copied);
+        SaveMapInformation(unwinder.GetProcessMemory(), info, &file_copied);
       }
     }
   }
diff --git a/logd/.clang-format b/logd/.clang-format
deleted file mode 100644
index 393c309..0000000
--- a/logd/.clang-format
+++ /dev/null
@@ -1,11 +0,0 @@
-BasedOnStyle: Google
-AllowShortFunctionsOnASingleLine: false
-
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-IndentWidth: 4
-PointerAlignment: Left
-TabWidth: 4
-PenaltyExcessCharacter: 32
-
-Cpp11BracedListStyle: false
diff --git a/logd/.clang-format b/logd/.clang-format
new file mode 120000
index 0000000..1af4f51
--- /dev/null
+++ b/logd/.clang-format
@@ -0,0 +1 @@
+../.clang-format-4
\ No newline at end of file
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index 18d5287..470ffed 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -300,7 +300,7 @@
         return 0;
     }
 
-    log_time now;
+    log_time now(log_time::EPOCH);
 
     static const char audit_str[] = " audit(";
     char* timeptr = strstr(str, audit_str);
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index fbdbf79..9cbc7c4 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -399,7 +399,7 @@
                         ((*it)->getLogId() != LOG_ID_KERNEL))) {
         mLogElements.push_back(elem);
     } else {
-        log_time end = log_time::EPOCH;
+        log_time end(log_time::EPOCH);
         bool end_set = false;
         bool end_always = false;
 
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
index 513c0c3..edd326a 100644
--- a/logd/LogKlog.cpp
+++ b/logd/LogKlog.cpp
@@ -197,10 +197,9 @@
     // NOTREACHED
 }
 
-log_time LogKlog::correction =
-    (log_time(CLOCK_REALTIME) < log_time(CLOCK_MONOTONIC))
-        ? log_time::EPOCH
-        : (log_time(CLOCK_REALTIME) - log_time(CLOCK_MONOTONIC));
+log_time LogKlog::correction = (log_time(CLOCK_REALTIME) < log_time(CLOCK_MONOTONIC))
+                                       ? log_time(log_time::EPOCH)
+                                       : (log_time(CLOCK_REALTIME) - log_time(CLOCK_MONOTONIC));
 
 LogKlog::LogKlog(LogBuffer* buf, LogReader* reader, int fdWrite, int fdRead,
                  bool auditd)
@@ -268,7 +267,7 @@
     static const char real_format[] = "%Y-%m-%d %H:%M:%S.%09q UTC";
     if (len < (ssize_t)(strlen(real_format) + 5)) return;
 
-    log_time real;
+    log_time real(log_time::EPOCH);
     const char* ep = real.strptime(real_string, real_format);
     if (!ep || (ep > &real_string[len]) || (real > log_time(CLOCK_REALTIME))) {
         return;
@@ -282,20 +281,20 @@
     tm.tm_isdst = -1;
     localtime_r(&now, &tm);
     if ((tm.tm_gmtoff < 0) && ((-tm.tm_gmtoff) > (long)real.tv_sec)) {
-        real = log_time::EPOCH;
+        real = log_time(log_time::EPOCH);
     } else {
         real.tv_sec += tm.tm_gmtoff;
     }
     if (monotonic > real) {
-        correction = log_time::EPOCH;
+        correction = log_time(log_time::EPOCH);
     } else {
         correction = real - monotonic;
     }
 }
 
-void LogKlog::sniffTime(log_time& now, const char*& buf, ssize_t len,
-                        bool reverse) {
-    if (len <= 0) return;
+log_time LogKlog::sniffTime(const char*& buf, ssize_t len, bool reverse) {
+    log_time now(log_time::EPOCH);
+    if (len <= 0) return now;
 
     const char* cp = nullptr;
     if ((len > 10) && (*buf == '[')) {
@@ -310,7 +309,7 @@
         }
         buf = cp;
 
-        if (isMonotonic()) return;
+        if (isMonotonic()) return now;
 
         const char* b;
         if (((b = android::strnstr(cp, len, suspendStr))) &&
@@ -329,11 +328,11 @@
             //     trigger a check for ntp-induced or hardware clock drift.
             log_time real(CLOCK_REALTIME);
             log_time mono(CLOCK_MONOTONIC);
-            correction = (real < mono) ? log_time::EPOCH : (real - mono);
+            correction = (real < mono) ? log_time(log_time::EPOCH) : (real - mono);
         } else if (((b = android::strnstr(cp, len, suspendedStr))) &&
                    (((b += strlen(suspendStr)) - cp) < len)) {
             len -= b - cp;
-            log_time real;
+            log_time real(log_time::EPOCH);
             char* endp;
             real.tv_sec = strtol(b, &endp, 10);
             if ((*endp == '.') && ((endp - b) < len)) {
@@ -345,7 +344,7 @@
                 }
                 if (reverse) {
                     if (real > correction) {
-                        correction = log_time::EPOCH;
+                        correction = log_time(log_time::EPOCH);
                     } else {
                         correction -= real;
                     }
@@ -363,6 +362,7 @@
             now = log_time(CLOCK_REALTIME);
         }
     }
+    return now;
 }
 
 pid_t LogKlog::sniffPid(const char*& buf, ssize_t len) {
@@ -451,8 +451,7 @@
     }
     parseKernelPrio(cp, len - (cp - buf));
 
-    log_time now;
-    sniffTime(now, cp, len - (cp - buf), true);
+    log_time now = sniffTime(cp, len - (cp - buf), true);
 
     const char* suspended = android::strnstr(buf, len, suspendedStr);
     if (!suspended || (suspended > cp)) {
@@ -468,7 +467,7 @@
     }
     parseKernelPrio(cp, len - (cp - buf));
 
-    sniffTime(now, cp, len - (cp - buf), true);
+    sniffTime(cp, len - (cp - buf), true);
 }
 
 // Convert kernel log priority number into an Android Logger priority number
@@ -548,8 +547,7 @@
     const char* p = buf;
     int pri = parseKernelPrio(p, len);
 
-    log_time now;
-    sniffTime(now, p, len - (p - buf), false);
+    log_time now = sniffTime(p, len - (p - buf), false);
 
     // sniff for start marker
     const char* start = android::strnstr(p, len - (p - buf), klogdStr);
diff --git a/logd/LogKlog.h b/logd/LogKlog.h
index bb92dd2..6bfd6a8 100644
--- a/logd/LogKlog.h
+++ b/logd/LogKlog.h
@@ -55,11 +55,10 @@
     }
 
    protected:
-    void sniffTime(log_time& now, const char*& buf, ssize_t len, bool reverse);
-    pid_t sniffPid(const char*& buf, ssize_t len);
-    void calculateCorrection(const log_time& monotonic, const char* real_string,
-                             ssize_t len);
-    virtual bool onDataAvailable(SocketClient* cli);
+     log_time sniffTime(const char*& buf, ssize_t len, bool reverse);
+     pid_t sniffPid(const char*& buf, ssize_t len);
+     void calculateCorrection(const log_time& monotonic, const char* real_string, ssize_t len);
+     virtual bool onDataAvailable(SocketClient* cli);
 };
 
 #endif
diff --git a/logd/LogTags.cpp b/logd/LogTags.cpp
index 1ab9dd1..f19e7b0 100644
--- a/logd/LogTags.cpp
+++ b/logd/LogTags.cpp
@@ -30,6 +30,7 @@
 
 #include <android-base/file.h>
 #include <android-base/macros.h>
+#include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
 #include <log/log_event_list.h>
 #include <log/log_properties.h>
@@ -38,6 +39,8 @@
 #include "LogTags.h"
 #include "LogUtils.h"
 
+using android::base::make_scope_guard;
+
 static LogTags* logtags;
 
 const char LogTags::system_event_log_tags[] = "/system/etc/event-log-tags";
@@ -316,27 +319,29 @@
         std::string Format;
         android_log_list_element elem;
         {
-            android_log_event_list ctx(log_msg);
-            elem = ctx.read();
+            auto ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
+                                                 log_msg.entry.len - sizeof(uint32_t));
+            auto guard = make_scope_guard([&ctx]() { android_log_destroy(&ctx); });
+            elem = android_log_read_next(ctx);
             if (elem.type != EVENT_TYPE_LIST) {
                 continue;
             }
-            elem = ctx.read();
+            elem = android_log_read_next(ctx);
             if (elem.type != EVENT_TYPE_INT) {
                 continue;
             }
             Tag = elem.data.int32;
-            elem = ctx.read();
+            elem = android_log_read_next(ctx);
             if (elem.type != EVENT_TYPE_STRING) {
                 continue;
             }
             Name = std::string(elem.data.string, elem.len);
-            elem = ctx.read();
+            elem = android_log_read_next(ctx);
             if (elem.type != EVENT_TYPE_STRING) {
                 continue;
             }
             Format = std::string(elem.data.string, elem.len);
-            elem = ctx.read();
+            elem = android_log_read_next(ctx);
         }
         if ((elem.type != EVENT_TYPE_LIST_STOP) || !elem.complete) continue;
 
@@ -524,10 +529,22 @@
     tag2format_const_iterator iform = tag2format.find(tag);
     std::string Format = (iform != tag2format.end()) ? iform->second : "";
 
-    __android_log_event_list ctx(TAG_DEF_LOG_TAG);
-    ctx << tag << Name << Format;
-    std::string buffer(ctx);
-    if (buffer.length() <= 0) return;  // unlikely
+    auto ctx = create_android_logger(TAG_DEF_LOG_TAG);
+    auto guard = make_scope_guard([&ctx]() { android_log_destroy(&ctx); });
+    if (android_log_write_int32(ctx, static_cast<int32_t>(tag) < 0) ||
+        android_log_write_string8_len(ctx, Name.c_str(), Name.size()) < 0 ||
+        android_log_write_string8_len(ctx, Format.c_str(), Format.size()) < 0) {
+        return;
+    }
+
+    const char* cp = nullptr;
+    ssize_t len = android_log_write_list_buffer(ctx, &cp);
+
+    if (len <= 0 || cp == nullptr) {
+        return;
+    }
+
+    std::string buffer(cp, len);
 
     /*
      *  struct {
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 372f481..9b20964 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -117,8 +117,6 @@
     mkdir /mnt/runtime/read/self 0755 root root
     mkdir /mnt/runtime/write 0755 root root
     mkdir /mnt/runtime/write/self 0755 root root
-    mkdir /mnt/runtime/full 0755 root root
-    mkdir /mnt/runtime/full/self 0755 root root
 
     # Symlink to keep legacy apps working in multi-user world
     symlink /storage/self/primary /sdcard
diff --git a/sdcard/sdcard.cpp b/sdcard/sdcard.cpp
index e1de130..dc36596 100644
--- a/sdcard/sdcard.cpp
+++ b/sdcard/sdcard.cpp
@@ -160,7 +160,6 @@
     std::string dest_path_default = "/mnt/runtime/default/" + label;
     std::string dest_path_read = "/mnt/runtime/read/" + label;
     std::string dest_path_write = "/mnt/runtime/write/" + label;
-    std::string dest_path_full = "/mnt/runtime/full/" + label;
 
     umask(0);
     if (multi_user) {
@@ -173,10 +172,7 @@
                                       default_normal, use_esdfs) ||
             !sdcardfs_setup_secondary(dest_path_default, source_path, dest_path_write, uid, gid,
                                       multi_user, userid, AID_EVERYBODY, full_write ? 0007 : 0027,
-                                      derive_gid, default_normal, use_esdfs) ||
-            !sdcardfs_setup_secondary(dest_path_default, source_path, dest_path_full, uid, gid,
-                                      multi_user, userid, AID_EVERYBODY, 0007, derive_gid,
-                                      default_normal, use_esdfs)) {
+                                      derive_gid, default_normal, use_esdfs)) {
             LOG(FATAL) << "failed to sdcardfs_setup";
         }
     } else {
@@ -190,10 +186,7 @@
                                       derive_gid, default_normal, use_esdfs) ||
             !sdcardfs_setup_secondary(dest_path_default, source_path, dest_path_write, uid, gid,
                                       multi_user, userid, AID_EVERYBODY, full_write ? 0007 : 0022,
-                                      derive_gid, default_normal, use_esdfs) ||
-            !sdcardfs_setup_secondary(dest_path_default, source_path, dest_path_full, uid, gid,
-                                      multi_user, userid, AID_EVERYBODY, 0007, derive_gid,
-                                      default_normal, use_esdfs)) {
+                                      derive_gid, default_normal, use_esdfs)) {
             LOG(FATAL) << "failed to sdcardfs_setup";
         }
     }
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp
index 77c6167..6897663 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -341,20 +341,14 @@
     if (mConfig.event_time_check_usec &&
         clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_ts) < 0) {
         check_time = false;
-        static time_t state_a;
-        IF_ALOG_RATELIMIT_LOCAL(300, &state_a) {
-            PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed";
-        }
+        PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed";
     }
 
     event();
 
     if (mConfig.event_time_check_usec && check_time) {
         if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_ts) < 0) {
-            static time_t state_b;
-            IF_ALOG_RATELIMIT_LOCAL(300, &state_b) {
-                PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed";
-            }
+            PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed";
             return;
         }
         int64_t cost = (end_ts.tv_sec - start_ts.tv_sec) * SEC_TO_USEC +
diff --git a/toolbox/getevent.c b/toolbox/getevent.c
index 39033ad..e2c77c3 100644
--- a/toolbox/getevent.c
+++ b/toolbox/getevent.c
@@ -530,6 +530,9 @@
     const char *device = NULL;
     const char *device_path = "/dev/input";
 
+    /* disable buffering on stdout */
+    setbuf(stdout, NULL);
+
     opterr = 0;
     do {
         c = getopt(argc, argv, "tns:Sv::dpilqc:rh");