Merge "Support parsing netlink route messages."
diff --git a/adb/services.c b/adb/services.c
index d1e8939..e48e460 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -189,13 +189,13 @@
 {
     setsid();
 
-    // Set OOM adjustment to prevent killing
-    int fd = adb_open("/proc/self/oom_adj", O_WRONLY);
+    // Set OOM score adjustment to prevent killing
+    int fd = adb_open("/proc/self/oom_score_adj", O_WRONLY);
     if (fd >= 0) {
         adb_write(fd, "0", 1);
         adb_close(fd);
     } else {
-       D("adb: unable to update oom_adj\n");
+       D("adb: unable to update oom_score_adj\n");
     }
 }
 
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index 705f02b..e7d8268 100755
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -84,6 +84,8 @@
 #define VENDOR_ID_HARRIS        0x19A5
 // Hisense's USB Vendor ID
 #define VENDOR_ID_HISENSE       0x109b
+// Honeywell's USB Vendor ID
+#define VENDOR_ID_HONEYWELL     0x0c2e
 // HP's USB Vendor ID
 #define VENDOR_ID_HP            0x03f0
 // HTC's USB Vendor ID
@@ -217,6 +219,7 @@
     VENDOR_ID_HAIER,
     VENDOR_ID_HARRIS,
     VENDOR_ID_HISENSE,
+    VENDOR_ID_HONEYWELL,
     VENDOR_ID_HP,
     VENDOR_ID_HTC,
     VENDOR_ID_HUAWEI,
diff --git a/debuggerd/arm64/machine.cpp b/debuggerd/arm64/machine.cpp
index f3409d5..48308c3 100644
--- a/debuggerd/arm64/machine.cpp
+++ b/debuggerd/arm64/machine.cpp
@@ -44,7 +44,7 @@
     io.iov_len = sizeof(regs);
 
     if (ptrace(PTRACE_GETREGSET, tid, (void*)NT_PRSTATUS, &io) == -1) {
-        LOG_ERROR("%s: ptrace failed to get registers: %s\n",
+        _LOG(log, logtype::ERROR, "%s: ptrace failed to get registers: %s\n",
              __func__, strerror(errno));
         return;
     }
@@ -80,7 +80,7 @@
   io.iov_len = sizeof(r);
 
   if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRSTATUS, (void*) &io) == -1) {
-    LOG_ERROR("ptrace error: %s\n", strerror(errno));
+    _LOG(log, logtype::ERROR, "ptrace error: %s\n", strerror(errno));
     return;
   }
 
@@ -105,7 +105,7 @@
   io.iov_len = sizeof(f);
 
   if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRFPREG, (void*) &io) == -1) {
-    LOG_ERROR("ptrace error: %s\n", strerror(errno));
+    _LOG(log, logtype::ERROR, "ptrace error: %s\n", strerror(errno));
     return;
   }
 
diff --git a/debuggerd/backtrace.cpp b/debuggerd/backtrace.cpp
index d08242e..50bc167 100644
--- a/debuggerd/backtrace.cpp
+++ b/debuggerd/backtrace.cpp
@@ -95,7 +95,7 @@
   }
 
   if (!attached && ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
-    LOG_ERROR("ptrace detach from %d failed: %s\n", tid, strerror(errno));
+    _LOG(log, logtype::ERROR, "ptrace detach from %d failed: %s\n", tid, strerror(errno));
     *detach_failed = true;
   }
 }
@@ -105,7 +105,6 @@
   log_t log;
   log.tfd = fd;
   log.amfd = amfd;
-  log.quiet = true;
 
   dump_process_header(&log, pid);
   dump_thread(&log, tid, true, detach_failed, total_sleep_time_usec);
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index dde8f90..ac0c36b 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -61,7 +61,7 @@
   char exe[PATH_MAX];
   int count;
   if ((count = readlink(path, exe, sizeof(exe) - 1)) == -1) {
-    LOG_ERROR("readlink('%s') failed: %s", path, strerror(errno));
+    ALOGE("readlink('%s') failed: %s", path, strerror(errno));
     strlcpy(exe, "unknown", sizeof(exe));
   } else {
     exe[count] = '\0';
@@ -78,17 +78,17 @@
   }
 
   // Explain how to attach the debugger.
-  LOG_ERROR(    "********************************************************\n"
-          "* Process %d has been suspended while crashing.\n"
-          "* To attach gdbserver for a gdb connection on port 5039\n"
-          "* and start gdbclient:\n"
-          "*\n"
-          "*     gdbclient %s :5039 %d\n"
-          "*\n"
-          "* Wait for gdb to start, then press the VOLUME DOWN key\n"
-          "* to let the process continue crashing.\n"
-          "********************************************************\n",
-          pid, name, pid);
+  ALOGI("********************************************************\n"
+        "* Process %d has been suspended while crashing.\n"
+        "* To attach gdbserver for a gdb connection on port 5039\n"
+        "* and start gdbclient:\n"
+        "*\n"
+        "*     gdbclient %s :5039 %d\n"
+        "*\n"
+        "* Wait for gdb to start, then press the VOLUME DOWN key\n"
+        "* to let the process continue crashing.\n"
+        "********************************************************\n",
+        pid, name, pid);
 
   // Wait for VOLUME DOWN.
   if (init_getevent() == 0) {
@@ -103,7 +103,7 @@
     uninit_getevent();
   }
 
-  LOG_ERROR("debuggerd resuming process %d", pid);
+  ALOGI("debuggerd resuming process %d", pid);
 }
 
 static int get_process_info(pid_t tid, pid_t* out_pid, uid_t* out_uid, uid_t* out_gid) {
@@ -139,11 +139,11 @@
   socklen_t len = sizeof(cr);
   int status = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
   if (status != 0) {
-    LOG_ERROR("cannot get credentials\n");
+    ALOGE("cannot get credentials\n");
     return -1;
   }
 
-  XLOG("reading tid\n");
+  ALOGV("reading tid\n");
   fcntl(fd, F_SETFL, O_NONBLOCK);
 
   pollfd pollfds[1];
@@ -152,7 +152,7 @@
   pollfds[0].revents = 0;
   status = TEMP_FAILURE_RETRY(poll(pollfds, 1, 3000));
   if (status != 1) {
-    LOG_ERROR("timed out reading tid (from pid=%d uid=%d)\n", cr.pid, cr.uid);
+    ALOGE("timed out reading tid (from pid=%d uid=%d)\n", cr.pid, cr.uid);
     return -1;
   }
 
@@ -160,14 +160,11 @@
   memset(&msg, 0, sizeof(msg));
   status = TEMP_FAILURE_RETRY(read(fd, &msg, sizeof(msg)));
   if (status < 0) {
-    LOG_ERROR("read failure? %s (pid=%d uid=%d)\n", strerror(errno), cr.pid, cr.uid);
+    ALOGE("read failure? %s (pid=%d uid=%d)\n", strerror(errno), cr.pid, cr.uid);
     return -1;
   }
-  if (status == sizeof(debugger_msg_t)) {
-    XLOG("crash request of size %d abort_msg_address=0x%" PRIPTR "\n",
-         status, msg.abort_msg_address);
-  } else {
-    LOG_ERROR("invalid crash request of size %d (from pid=%d uid=%d)\n", status, cr.pid, cr.uid);
+  if (status != sizeof(debugger_msg_t)) {
+    ALOGE("invalid crash request of size %d (from pid=%d uid=%d)\n", status, cr.pid, cr.uid);
     return -1;
   }
 
@@ -185,7 +182,7 @@
     struct stat s;
     snprintf(buf, sizeof buf, "/proc/%d/task/%d", out_request->pid, out_request->tid);
     if (stat(buf, &s)) {
-      LOG_ERROR("tid %d does not exist in pid %d. ignoring debug request\n",
+      ALOGE("tid %d does not exist in pid %d. ignoring debug request\n",
           out_request->tid, out_request->pid);
       return -1;
     }
@@ -196,7 +193,7 @@
     status = get_process_info(out_request->tid, &out_request->pid,
                               &out_request->uid, &out_request->gid);
     if (status < 0) {
-      LOG_ERROR("tid %d does not exist. ignoring explicit dump request\n", out_request->tid);
+      ALOGE("tid %d does not exist. ignoring explicit dump request\n", out_request->tid);
       return -1;
     }
   } else {
@@ -217,13 +214,13 @@
 }
 
 static void handle_request(int fd) {
-  XLOG("handle_request(%d)\n", fd);
+  ALOGV("handle_request(%d)\n", fd);
 
   debugger_request_t request;
   memset(&request, 0, sizeof(request));
   int status = read_request(fd, &request);
   if (!status) {
-    XLOG("BOOM: pid=%d uid=%d gid=%d tid=%d\n",
+    ALOGV("BOOM: pid=%d uid=%d gid=%d tid=%d\n",
          request.pid, request.uid, request.gid, request.tid);
 
     // At this point, the thread that made the request is blocked in
@@ -237,12 +234,12 @@
     // See details in bionic/libc/linker/debugger.c, in function
     // debugger_signal_handler().
     if (ptrace(PTRACE_ATTACH, request.tid, 0, 0)) {
-      LOG_ERROR("ptrace attach failed: %s\n", strerror(errno));
+      ALOGE("ptrace attach failed: %s\n", strerror(errno));
     } else {
       bool detach_failed = false;
       bool attach_gdb = should_attach_gdb(&request);
       if (TEMP_FAILURE_RETRY(write(fd, "\0", 1)) != 1) {
-        LOG_ERROR("failed responding to client: %s\n", strerror(errno));
+        ALOGE("failed responding to client: %s\n", strerror(errno));
       } else {
         char* tombstone_path = NULL;
 
@@ -261,20 +258,20 @@
           switch (signal) {
             case SIGSTOP:
               if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
-                XLOG("stopped -- dumping to tombstone\n");
+                ALOGV("stopped -- dumping to tombstone\n");
                 tombstone_path = engrave_tombstone(request.pid, request.tid,
                                                    signal, request.original_si_code,
-                                                   request.abort_msg_address, true, true,
+                                                   request.abort_msg_address, true,
                                                    &detach_failed, &total_sleep_time_usec);
               } else if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE) {
-                XLOG("stopped -- dumping to fd\n");
+                ALOGV("stopped -- dumping to fd\n");
                 dump_backtrace(fd, -1, request.pid, request.tid, &detach_failed,
                                &total_sleep_time_usec);
               } else {
-                XLOG("stopped -- continuing\n");
+                ALOGV("stopped -- continuing\n");
                 status = ptrace(PTRACE_CONT, request.tid, 0, 0);
                 if (status) {
-                  LOG_ERROR("ptrace continue failed: %s\n", strerror(errno));
+                  ALOGE("ptrace continue failed: %s\n", strerror(errno));
                 }
                 continue; // loop again
               }
@@ -290,7 +287,7 @@
             case SIGSTKFLT:
 #endif
             case SIGTRAP:
-              XLOG("stopped -- fatal signal\n");
+              ALOGV("stopped -- fatal signal\n");
               // Send a SIGSTOP to the process to make all of
               // the non-signaled threads stop moving.  Without
               // this we get a lot of "ptrace detach failed:
@@ -300,13 +297,12 @@
               // makes the process less reliable, apparently...
               tombstone_path = engrave_tombstone(request.pid, request.tid,
                                                  signal, request.original_si_code,
-                                                 request.abort_msg_address, !attach_gdb, false,
+                                                 request.abort_msg_address, !attach_gdb,
                                                  &detach_failed, &total_sleep_time_usec);
               break;
 
             default:
-              XLOG("stopped -- unexpected signal\n");
-              LOG_ERROR("process stopped due to unexpected signal %d\n", signal);
+              ALOGE("process stopped due to unexpected signal %d\n", signal);
               break;
           }
           break;
@@ -322,14 +318,14 @@
         free(tombstone_path);
       }
 
-      XLOG("detaching\n");
+      ALOGV("detaching\n");
       if (attach_gdb) {
         // stop the process so we can debug
         kill(request.pid, SIGSTOP);
 
         // detach so we can attach gdbserver
         if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) {
-          LOG_ERROR("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
+          ALOGE("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
           detach_failed = true;
         }
 
@@ -341,7 +337,7 @@
       } else {
         // just detach
         if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) {
-          LOG_ERROR("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
+          ALOGE("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
           detach_failed = true;
         }
       }
@@ -353,7 +349,7 @@
       // actual parent won't receive a death notification via wait(2).  At this point
       // there's not much we can do about that.
       if (detach_failed) {
-        LOG_ERROR("debuggerd committing suicide to free the zombie!\n");
+        ALOGE("debuggerd committing suicide to free the zombie!\n");
         kill(getpid(), SIGKILL);
       }
     }
@@ -399,16 +395,16 @@
     return 1;
   fcntl(s, F_SETFD, FD_CLOEXEC);
 
-  LOG_ERROR("debuggerd: " __DATE__ " " __TIME__ "\n");
+  ALOGI("debuggerd: " __DATE__ " " __TIME__ "\n");
 
   for (;;) {
     sockaddr addr;
     socklen_t alen = sizeof(addr);
 
-    XLOG("waiting for connection\n");
+    ALOGV("waiting for connection\n");
     int fd = accept(s, &addr, &alen);
     if (fd < 0) {
-      XLOG("accept failed: %s\n", strerror(errno));
+      ALOGV("accept failed: %s\n", strerror(errno));
       continue;
     }
 
diff --git a/debuggerd/mips/machine.cpp b/debuggerd/mips/machine.cpp
index 605275b..97834c7 100644
--- a/debuggerd/mips/machine.cpp
+++ b/debuggerd/mips/machine.cpp
@@ -87,7 +87,7 @@
 void dump_registers(log_t* log, pid_t tid) {
   pt_regs_mips_t r;
   if(ptrace(PTRACE_GETREGS, tid, 0, &r)) {
-    LOG_ERROR("cannot get registers: %s\n", strerror(errno));
+    _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
     return;
   }
 
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index d79f9e2..211e56a 100755
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -343,8 +343,9 @@
   }
 }
 
-static void dump_map(log_t* log, const backtrace_map_t* map) {
-  _LOG(log, logtype::MAPS, "    %" PRIPTR "-%" PRIPTR " %c%c%c %s\n", map->start, map->end,
+static void dump_map(log_t* log, const backtrace_map_t* map, bool fault_addr) {
+  _LOG(log, logtype::MAPS, "%s%" PRIPTR "-%" PRIPTR " %c%c%c %s\n",
+         (fault_addr? "--->" : "    "), map->start, map->end,
          (map->flags & PROT_READ) ? 'r' : '-', (map->flags & PROT_WRITE) ? 'w' : '-',
          (map->flags & PROT_EXEC) ? 'x' : '-', map->name.c_str());
 }
@@ -366,10 +367,18 @@
     return;
   }
 
-  _LOG(log, logtype::MAPS, "\nmemory map:\n");
+  _LOG(log, logtype::MAPS, "\nmemory map: (fault address prefixed with --->)\n");
 
+  bool found_map = false;
   for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) {
-    dump_map(log, &*it);
+    bool in_map = addr >= (*it).start && addr < (*it).end;
+    dump_map(log, &*it, in_map);
+    if(in_map) {
+      found_map = true;
+    }
+  }
+  if(!found_map) {
+    _LOG(log, logtype::ERROR, "\nFault address was not in any map!");
   }
 }
 
@@ -395,7 +404,7 @@
   DIR* d = opendir(task_path);
   // Bail early if the task directory cannot be opened
   if (d == NULL) {
-    XLOG("Cannot open /proc/%d/task\n", pid);
+    ALOGE("Cannot open /proc/%d/task\n", pid);
     return false;
   }
 
@@ -416,7 +425,7 @@
 
     // Skip this thread if cannot ptrace it
     if (ptrace(PTRACE_ATTACH, new_tid, 0, 0) < 0) {
-      LOG_ERROR("ptrace attach to %d failed: %s\n", new_tid, strerror(errno));
+      _LOG(log, logtype::ERROR, "ptrace attach to %d failed: %s\n", new_tid, strerror(errno));
       continue;
     }
 
@@ -433,7 +442,7 @@
     log->current_tid = log->crashed_tid;
 
     if (ptrace(PTRACE_DETACH, new_tid, 0, 0) != 0) {
-      LOG_ERROR("ptrace detach from %d failed: %s\n", new_tid, strerror(errno));
+      _LOG(log, logtype::ERROR, "ptrace detach from %d failed: %s\n", new_tid, strerror(errno));
       detach_failed = true;
     }
   }
@@ -457,7 +466,7 @@
       android_name_to_log_id(filename), O_RDONLY | O_NONBLOCK, tail, pid);
 
   if (!logger_list) {
-    XLOG("Unable to open %s: %s\n", filename, strerror(errno));
+    ALOGE("Unable to open %s: %s\n", filename, strerror(errno));
     return;
   }
 
@@ -475,16 +484,17 @@
         // non-blocking EOF; we're done
         break;
       } else {
-        LOG_ERROR("Error while reading log: %s\n", strerror(-actual));
+        _LOG(log, logtype::ERROR, "Error while reading log: %s\n",
+          strerror(-actual));
         break;
       }
     } else if (actual == 0) {
-      LOG_ERROR("Got zero bytes while reading log: %s\n",
+      _LOG(log, logtype::ERROR, "Got zero bytes while reading log: %s\n",
         strerror(errno));
       break;
     }
 
-    // NOTE: if you XLOG something here, this will spin forever,
+    // NOTE: if you ALOGV something here, this will spin forever,
     // because you will be writing as fast as you're reading.  Any
     // high-frequency debug diagnostics should just be written to
     // the tombstone file.
@@ -684,7 +694,7 @@
   }
 
   if (oldest < 0) {
-    LOG_ERROR("Failed to find a valid tombstone, default to using tombstone 0.\n");
+    ALOGE("Failed to find a valid tombstone, default to using tombstone 0.\n");
     oldest = 0;
   }
 
@@ -692,7 +702,7 @@
   snprintf(path, sizeof(path), TOMBSTONE_TEMPLATE, oldest);
   *fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
   if (*fd < 0) {
-    LOG_ERROR("failed to open tombstone file '%s': %s\n", path, strerror(errno));
+    ALOGE("failed to open tombstone file '%s': %s\n", path, strerror(errno));
     return NULL;
   }
   fchown(*fd, AID_SYSTEM, AID_SYSTEM);
@@ -730,7 +740,7 @@
 }
 
 char* engrave_tombstone(pid_t pid, pid_t tid, int signal, int original_si_code,
-                        uintptr_t abort_msg_address, bool dump_sibling_threads, bool quiet,
+                        uintptr_t abort_msg_address, bool dump_sibling_threads,
                         bool* detach_failed, int* total_sleep_time_usec) {
 
   log_t log;
@@ -738,11 +748,11 @@
   log.crashed_tid = tid;
 
   if ((mkdir(TOMBSTONE_DIR, 0755) == -1) && (errno != EEXIST)) {
-    LOG_ERROR("failed to create %s: %s\n", TOMBSTONE_DIR, strerror(errno));
+    _LOG(&log, logtype::ERROR, "failed to create %s: %s\n", TOMBSTONE_DIR, strerror(errno));
   }
 
   if (chown(TOMBSTONE_DIR, AID_SYSTEM, AID_SYSTEM) == -1) {
-    LOG_ERROR("failed to change ownership of %s: %s\n", TOMBSTONE_DIR, strerror(errno));
+    _LOG(&log, logtype::ERROR, "failed to change ownership of %s: %s\n", TOMBSTONE_DIR, strerror(errno));
   }
 
   int fd = -1;
@@ -750,11 +760,11 @@
   if (selinux_android_restorecon(TOMBSTONE_DIR, 0) == 0) {
     path = find_and_open_tombstone(&fd);
   } else {
-    LOG_ERROR("Failed to restore security context, not writing tombstone.\n");
+    _LOG(&log, logtype::ERROR, "Failed to restore security context, not writing tombstone.\n");
   }
 
-  if (fd < 0 && quiet) {
-    LOG_ERROR("Skipping tombstone write, nothing to do.\n");
+  if (fd < 0) {
+    _LOG(&log, logtype::ERROR, "Skipping tombstone write, nothing to do.\n");
     *detach_failed = false;
     return NULL;
   }
@@ -764,7 +774,6 @@
   // being closed.
   int amfd = activity_manager_connect();
   log.amfd = amfd;
-  log.quiet = quiet;
   *detach_failed = dump_crash(&log, pid, tid, signal, original_si_code, abort_msg_address,
                               dump_sibling_threads, total_sleep_time_usec);
 
diff --git a/debuggerd/tombstone.h b/debuggerd/tombstone.h
index 3574e84..7e2b2fe 100644
--- a/debuggerd/tombstone.h
+++ b/debuggerd/tombstone.h
@@ -25,7 +25,7 @@
  * Returns the path of the tombstone, which must be freed using free(). */
 char* engrave_tombstone(pid_t pid, pid_t tid, int signal, int original_si_code,
                         uintptr_t abort_msg_address,
-                        bool dump_sibling_threads, bool quiet,
-                        bool* detach_failed, int* total_sleep_time_usec);
+                        bool dump_sibling_threads, bool* detach_failed,
+                        int* total_sleep_time_usec);
 
 #endif // _DEBUGGERD_TOMBSTONE_H
diff --git a/debuggerd/utility.cpp b/debuggerd/utility.cpp
index f0d9220..a163344 100644
--- a/debuggerd/utility.cpp
+++ b/debuggerd/utility.cpp
@@ -37,7 +37,7 @@
     int written = TEMP_FAILURE_RETRY(write(fd, buf + len - to_write, to_write));
     if (written < 0) {
       // hard failure
-      LOG_ERROR("AM write failure (%d / %s)\n", errno, strerror(errno));
+      ALOGE("AM write failure (%d / %s)\n", errno, strerror(errno));
       return -1;
     }
     to_write -= written;
@@ -57,12 +57,10 @@
 }
 
 void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) {
-  bool write_to_tombstone = log && log->tfd;
-  bool write_to_logcat = (!log || !log->quiet) && is_allowed_in_logcat(ltype);
-  if (log != NULL) {
-    write_to_logcat &= (log->crashed_tid == log->current_tid);
-  }
-  bool write_to_activitymanager = log && log->amfd >= 0 && is_allowed_in_logcat(ltype);
+  bool write_to_tombstone = (log->tfd != -1);
+  bool write_to_logcat = is_allowed_in_logcat(ltype)
+                      && (log->crashed_tid == log->current_tid);
+  bool write_to_activitymanager = (log->amfd != -1);
 
   char buf[512];
   va_list ap;
@@ -98,25 +96,25 @@
     if (n < 0) {
       if (errno == EAGAIN)
         continue;
-      LOG_ERROR("waitpid failed: %s\n", strerror(errno));
+      ALOGE("waitpid failed: %s\n", strerror(errno));
       return -1;
     } else if (n > 0) {
-      XLOG("waitpid: n=%d status=%08x\n", n, status);
+      ALOGV("waitpid: n=%d status=%08x\n", n, status);
       if (WIFSTOPPED(status)) {
         return WSTOPSIG(status);
       } else {
-        LOG_ERROR("unexpected waitpid response: n=%d, status=%08x\n", n, status);
+        ALOGE("unexpected waitpid response: n=%d, status=%08x\n", n, status);
         return -1;
       }
     }
 
     if (*total_sleep_time_usec > max_total_sleep_usec) {
-      LOG_ERROR("timed out waiting for tid=%d to die\n", tid);
+      ALOGE("timed out waiting for tid=%d to die\n", tid);
       return -1;
     }
 
     // not ready yet
-    XLOG("not ready yet\n");
+    ALOGV("not ready yet\n");
     usleep(sleep_time_usec);
     *total_sleep_time_usec += sleep_time_usec;
   }
@@ -126,7 +124,7 @@
   siginfo_t si;
   while (TEMP_FAILURE_RETRY(ptrace(PTRACE_GETSIGINFO, tid, 0, &si)) < 0 && errno == ESRCH) {
     if (*total_sleep_time_usec > max_total_sleep_usec) {
-      LOG_ERROR("timed out waiting for tid=%d to stop\n", tid);
+      ALOGE("timed out waiting for tid=%d to stop\n", tid);
       break;
     }
 
diff --git a/debuggerd/utility.h b/debuggerd/utility.h
index fdfb2ec..ee4f035 100644
--- a/debuggerd/utility.h
+++ b/debuggerd/utility.h
@@ -26,8 +26,6 @@
     int tfd;
     /* Activity Manager socket file descriptor */
     int amfd;
-    /* if true, does not log anything to the Android logcat or Activity Manager */
-    bool quiet;
     // The tid of the thread that crashed.
     pid_t crashed_tid;
     // The tid of the thread we are currently working with.
@@ -51,10 +49,6 @@
 void _LOG(log_t* log, logtype ltype, const char *fmt, ...)
         __attribute__ ((format(printf, 3, 4)));
 
-/* Further helpful macros */
-#define LOG_ERROR(fmt...) _LOG(NULL, logtype::ERROR, fmt)
-#define XLOG(fmt...) do {} while(0)
-
 int wait_for_signal(pid_t tid, int* total_sleep_time_usec);
 void wait_for_stop(pid_t tid, int* total_sleep_time_usec);
 
diff --git a/debuggerd/x86/machine.cpp b/debuggerd/x86/machine.cpp
index 2d553fa..57330c1 100644
--- a/debuggerd/x86/machine.cpp
+++ b/debuggerd/x86/machine.cpp
@@ -31,7 +31,7 @@
 void dump_registers(log_t* log, pid_t tid) {
   struct pt_regs r;
   if (ptrace(PTRACE_GETREGS, tid, 0, &r) == -1) {
-    LOG_ERROR("cannot get registers: %s\n", strerror(errno));
+    _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
     return;
   }
   _LOG(log, logtype::REGISTERS, "    eax %08lx  ebx %08lx  ecx %08lx  edx %08lx\n",
diff --git a/debuggerd/x86_64/machine.cpp b/debuggerd/x86_64/machine.cpp
index 6cb0e8d..af4f35a 100755
--- a/debuggerd/x86_64/machine.cpp
+++ b/debuggerd/x86_64/machine.cpp
@@ -33,7 +33,7 @@
 void dump_registers(log_t* log, pid_t tid) {
     struct user_regs_struct r;
     if (ptrace(PTRACE_GETREGS, tid, 0, &r) == -1) {
-        LOG_ERROR("cannot get registers: %s\n", strerror(errno));
+        _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
         return;
     }
     _LOG(log, logtype::REGISTERS, "    rax %016lx  rbx %016lx  rcx %016lx  rdx %016lx\n",
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 0238404..252db6c 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -66,7 +66,7 @@
 ifeq ($(HOST_OS),linux)
 # libf2fs_dlutils_host will dlopen("libf2fs_fmt_host_dyn")
 LOCAL_CFLAGS += -DUSE_F2FS
-LOCAL_LDFLAGS += -ldl -rdynamic
+LOCAL_LDFLAGS += -ldl -rdynamic -Wl,-rpath,.
 LOCAL_REQUIRED_MODULES := libf2fs_fmt_host_dyn
 # The following libf2fs_* are from system/extras/f2fs_utils,
 # and do not use code in external/f2fs-tools.
@@ -75,8 +75,12 @@
 
 include $(BUILD_HOST_EXECUTABLE)
 
-
-$(call dist-for-goals,dist_files sdk,$(LOCAL_BUILT_MODULE))
+my_dist_files := $(LOCAL_BUILT_MODULE)
+ifeq ($(HOST_OS),linux)
+my_dist_files += $(HOST_LIBRARY_PATH)/libf2fs_fmt_host_dyn$(HOST_SHLIB_SUFFIX)
+endif
+$(call dist-for-goals,dist_files sdk,$(my_dist_files))
+my_dist_files :=
 
 
 ifeq ($(HOST_OS),linux)
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 183712a..c7a123d 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -31,6 +31,7 @@
 
 #include <linux/loop.h>
 #include <private/android_filesystem_config.h>
+#include <cutils/android_reboot.h>
 #include <cutils/partition_utils.h>
 #include <cutils/properties.h>
 #include <logwrap/logwrap.h>
@@ -236,6 +237,19 @@
     return strcmp(value, "1") ? 0 : 1;
 }
 
+void wipe_data_via_recovery()
+{
+    mkdir("/cache/recovery", 0700);
+    int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC, 0600);
+    if (fd >= 0) {
+        write(fd, "--wipe_data", strlen("--wipe_data") + 1);
+        close(fd);
+    } else {
+        ERROR("could not open /cache/recovery/command\n");
+    }
+    property_set(ANDROID_RB_PROPERTY, "reboot,recovery");
+}
+
 /* When multiple fstab records share the same mount_point, it will
  * try to mount each one in turn, and ignore any duplicates after a
  * first successful mount.
@@ -273,7 +287,7 @@
         if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
             !device_is_debuggable()) {
             if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
-                ERROR("Could not set up verified partition, skipping!");
+                ERROR("Could not set up verified partition, skipping!\n");
                 continue;
             }
         }
@@ -320,11 +334,11 @@
                     if (!encryptable) {
                         encryptable = 2;
                     } else {
-                        ERROR("Only one encryptable/encrypted partition supported");
+                        ERROR("Only one encryptable/encrypted partition supported\n");
                         encryptable = 1;
                     }
                 } else {
-                    INFO("Could not umount %s - allow continue unencrypted",
+                    INFO("Could not umount %s - allow continue unencrypted\n",
                          fstab->recs[i].mount_point);
                     continue;
                 }
@@ -335,14 +349,20 @@
 
         /* mount(2) returned an error, check if it's encryptable and deal with it */
         if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
-            (fstab->recs[i].fs_mgr_flags & (MF_CRYPT | MF_FORCECRYPT)) &&
-            !partition_wiped(fstab->recs[i].blk_device)) {
-            /* Need to mount a tmpfs at this mountpoint for now, and set
-             * properties that vold will query later for decrypting
-             */
-            if (fs_mgr_do_tmpfs_mount(fstab->recs[i].mount_point) < 0) {
+            fs_mgr_is_encryptable(&fstab->recs[i])) {
+            if(partition_wiped(fstab->recs[i].blk_device) && fstab->recs[i].fs_mgr_flags & MF_FORCECRYPT) {
+                ERROR("Found an encryptable wiped partition with force encrypt. Formating via recovery.\n");
+                wipe_data_via_recovery();  /* This is queue up a reboot */
                 ++error_count;
                 continue;
+            } else {
+                /* Need to mount a tmpfs at this mountpoint for now, and set
+                 * properties that vold will query later for decrypting
+                 */
+                if (fs_mgr_do_tmpfs_mount(fstab->recs[i].mount_point) < 0) {
+                    ++error_count;
+                    continue;
+                }
             }
             encryptable = 1;
         } else {
@@ -408,7 +428,7 @@
         if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
             !device_is_debuggable()) {
             if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
-                ERROR("Could not set up verified partition, skipping!");
+                ERROR("Could not set up verified partition, skipping!\n");
                 continue;
             }
         }
@@ -515,7 +535,7 @@
 
             zram_fp = fopen(ZRAM_CONF_DEV, "r+");
             if (zram_fp == NULL) {
-                ERROR("Unable to open zram conf device " ZRAM_CONF_DEV);
+                ERROR("Unable to open zram conf device %s\n", ZRAM_CONF_DEV);
                 ret = -1;
                 continue;
             }
diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp
index a1912f1..30a4b42 100644
--- a/healthd/healthd.cpp
+++ b/healthd/healthd.cpp
@@ -205,7 +205,7 @@
     healthd_battery_update();
 }
 
-#define UEVENT_MSG_LEN 1024
+#define UEVENT_MSG_LEN 2048
 static void uevent_event(uint32_t /*epevents*/) {
     char msg[UEVENT_MSG_LEN+2];
     char *cp;
diff --git a/include/system/audio.h b/include/system/audio.h
index cc4137e..c7cd109 100644
--- a/include/system/audio.h
+++ b/include/system/audio.h
@@ -229,6 +229,8 @@
     AUDIO_FORMAT_HE_AAC_V2           = 0x06000000UL,
     AUDIO_FORMAT_VORBIS              = 0x07000000UL,
     AUDIO_FORMAT_OPUS                = 0x08000000UL,
+    AUDIO_FORMAT_AC3                 = 0x09000000UL,
+    AUDIO_FORMAT_E_AC3               = 0x0A000000UL,
     AUDIO_FORMAT_MAIN_MASK           = 0xFF000000UL,
     AUDIO_FORMAT_SUB_MASK            = 0x00FFFFFFUL,
 
@@ -1009,6 +1011,9 @@
     case AUDIO_FORMAT_HE_AAC_V1:
     case AUDIO_FORMAT_HE_AAC_V2:
     case AUDIO_FORMAT_VORBIS:
+    case AUDIO_FORMAT_OPUS:
+    case AUDIO_FORMAT_AC3:
+    case AUDIO_FORMAT_E_AC3:
         return true;
     default:
         return false;
diff --git a/init/devices.c b/init/devices.c
index 02698ef..ea9a4b2 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -15,6 +15,7 @@
  */
 
 #include <errno.h>
+#include <fnmatch.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -77,6 +78,7 @@
     unsigned int uid;
     unsigned int gid;
     unsigned short prefix;
+    unsigned short wildcard;
 };
 
 struct perm_node {
@@ -97,7 +99,8 @@
 
 int add_dev_perms(const char *name, const char *attr,
                   mode_t perm, unsigned int uid, unsigned int gid,
-                  unsigned short prefix) {
+                  unsigned short prefix,
+                  unsigned short wildcard) {
     struct perm_node *node = calloc(1, sizeof(*node));
     if (!node)
         return -ENOMEM;
@@ -116,6 +119,7 @@
     node->dp.uid = uid;
     node->dp.gid = gid;
     node->dp.prefix = prefix;
+    node->dp.wildcard = wildcard;
 
     if (attr)
         list_add_tail(&sys_perms, &node->plist);
@@ -140,6 +144,9 @@
         if (dp->prefix) {
             if (strncmp(upath, dp->name + 4, strlen(dp->name + 4)))
                 continue;
+        } else if (dp->wildcard) {
+            if (fnmatch(dp->name + 4, upath, FNM_PATHNAME) != 0)
+                continue;
         } else {
             if (strcmp(upath, dp->name + 4))
                 continue;
@@ -180,6 +187,9 @@
         if (dp->prefix) {
             if (strncmp(path, dp->name, strlen(dp->name)))
                 continue;
+        } else if (dp->wildcard) {
+            if (fnmatch(dp->name, path, FNM_PATHNAME) != 0)
+                continue;
         } else {
             if (strcmp(path, dp->name))
                 continue;
diff --git a/init/devices.h b/init/devices.h
index a84fa58..5d0fe88 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -23,6 +23,7 @@
 extern void device_init(void);
 extern int add_dev_perms(const char *name, const char *attr,
                          mode_t perm, unsigned int uid,
-                         unsigned int gid, unsigned short prefix);
+                         unsigned int gid, unsigned short prefix,
+                         unsigned short wildcard);
 int get_device_fd();
 #endif	/* _INIT_DEVICES_H */
diff --git a/init/ueventd.c b/init/ueventd.c
index 662196d..4ad0cb9 100644
--- a/init/ueventd.c
+++ b/init/ueventd.c
@@ -122,6 +122,7 @@
     uid_t uid;
     gid_t gid;
     int prefix = 0;
+    int wildcard = 0;
     char *endptr;
     int ret;
     char *tmp = 0;
@@ -154,9 +155,13 @@
         name = tmp;
     } else {
         int len = strlen(name);
-        if (name[len - 1] == '*') {
+        char *wildcard_chr = strchr(name, '*');
+        if ((name[len - 1] == '*') &&
+            (wildcard_chr == (name + len - 1))) {
             prefix = 1;
             name[len - 1] = '\0';
+        } else if (wildcard_chr) {
+            wildcard = 1;
         }
     }
 
@@ -183,6 +188,6 @@
     }
     gid = ret;
 
-    add_dev_perms(name, attr, perm, uid, gid, prefix);
+    add_dev_perms(name, attr, perm, uid, gid, prefix, wildcard);
     free(tmp);
 }
diff --git a/rootdir/init.rc b/rootdir/init.rc
index a016657..8a4a37d 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -26,29 +26,28 @@
 
     start ueventd
 
-# create mountpoints
+    # create mountpoints
     mkdir /mnt 0775 root system
 
 on init
+    sysclktz 0
 
-sysclktz 0
+    loglevel 3
 
-loglevel 3
-
-# Backward compatibility
+    # Backward compatibility
     symlink /system/etc /etc
     symlink /sys/kernel/debug /d
 
-# Right now vendor lives on the same filesystem as system,
-# but someday that may change.
+    # Right now vendor lives on the same filesystem as system,
+    # but someday that may change.
     symlink /system/vendor /vendor
 
-# Create cgroup mount point for cpu accounting
+    # Create cgroup mount point for cpu accounting
     mkdir /acct
     mount cgroup none /acct cpuacct
     mkdir /acct/uid
 
-# Create cgroup mount point for memory
+    # Create cgroup mount point for memory
     mount tmpfs none /sys/fs/cgroup mode=0750,uid=0,gid=1000
     mkdir /sys/fs/cgroup/memory 0750 root system
     mount cgroup none /sys/fs/cgroup/memory memory
@@ -115,7 +114,7 @@
     # set fwmark on accepted sockets
     write /proc/sys/net/ipv4/tcp_fwmark_accept 1
 
-# Create cgroup mount points for process groups
+    # Create cgroup mount points for process groups
     mkdir /dev/cpuctl
     mount cgroup none /dev/cpuctl cpu
     chown system system /dev/cpuctl
@@ -140,21 +139,21 @@
     write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_runtime_us 700000
     write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_period_us 1000000
 
-# qtaguid will limit access to specific data based on group memberships.
-#   net_bw_acct grants impersonation of socket owners.
-#   net_bw_stats grants access to other apps' detailed tagged-socket stats.
+    # qtaguid will limit access to specific data based on group memberships.
+    #   net_bw_acct grants impersonation of socket owners.
+    #   net_bw_stats grants access to other apps' detailed tagged-socket stats.
     chown root net_bw_acct /proc/net/xt_qtaguid/ctrl
     chown root net_bw_stats /proc/net/xt_qtaguid/stats
 
-# Allow everybody to read the xt_qtaguid resource tracking misc dev.
-# This is needed by any process that uses socket tagging.
+    # Allow everybody to read the xt_qtaguid resource tracking misc dev.
+    # This is needed by any process that uses socket tagging.
     chmod 0644 /dev/xt_qtaguid
 
-# Create location for fs_mgr to store abbreviated output from filesystem
-# checker programs.
+    # Create location for fs_mgr to store abbreviated output from filesystem
+    # checker programs.
     mkdir /dev/fscklogs 0770 root system
 
-# pstore/ramoops previous console log
+    # pstore/ramoops previous console log
     mount pstore pstore /sys/fs/pstore
     chown system log /sys/fs/pstore/console-ramoops
     chmod 0440 /sys/fs/pstore/console-ramoops
@@ -299,17 +298,17 @@
     #setprop vold.post_fs_data_done 1
 
 on boot
-# basic network init
+    # basic network init
     ifup lo
     hostname localhost
     domainname localdomain
 
-# set RLIMIT_NICE to allow priorities from 19 to -20
+    # set RLIMIT_NICE to allow priorities from 19 to -20
     setrlimit 13 40 40
 
-# Memory management.  Basic kernel parameters, and allow the high
-# level system server to be able to adjust the kernel OOM driver
-# parameters to match how it is managing things.
+    # Memory management.  Basic kernel parameters, and allow the high
+    # level system server to be able to adjust the kernel OOM driver
+    # parameters to match how it is managing things.
     write /proc/sys/vm/overcommit_memory 1
     write /proc/sys/vm/min_free_order_shift 4
     chown root system /sys/module/lowmemorykiller/parameters/adj
@@ -385,8 +384,8 @@
     chown system system /sys/kernel/ipv4/tcp_rmem_max
     chown root radio /proc/cmdline
 
-# Define TCP buffer sizes for various networks
-#   ReadMin, ReadInitial, ReadMax, WriteMin, WriteInitial, WriteMax,
+    # Define TCP buffer sizes for various networks
+    #   ReadMin, ReadInitial, ReadMax, WriteMin, WriteInitial, WriteMax,
     setprop net.tcp.buffersize.default  4096,87380,110208,4096,16384,110208
     setprop net.tcp.buffersize.wifi     524288,1048576,2097152,262144,524288,1048576
     setprop net.tcp.buffersize.ethernet 524288,1048576,3145728,524288,1048576,2097152
@@ -400,7 +399,7 @@
     setprop net.tcp.buffersize.gprs     4092,8760,48000,4096,8760,48000
     setprop net.tcp.buffersize.evdo     4094,87380,262144,4096,16384,262144
 
-# Define default initial receive window size in segments.
+    # Define default initial receive window size in segments.
     setprop net.tcp.default_init_rwnd 60
 
     class_start core
@@ -448,6 +447,7 @@
 # So proxy writes through init.
 on property:sys.sysctl.extra_free_kbytes=*
     write /proc/sys/vm/extra_free_kbytes ${sys.sysctl.extra_free_kbytes}
+
 # "tcp_default_init_rwnd" Is too long!
 on property:sys.sysctl.tcp_def_init_rwnd=*
     write /proc/sys/net/ipv4/tcp_default_init_rwnd ${sys.sysctl.tcp_def_init_rwnd}