Merge "Compare two bootcharts and list timestamps for selected processes."
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 371525c..9af1586 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -552,6 +552,7 @@
     /* we create a PIPE that will be used to wait for the server's "OK" */
     /* message since the pipe handles must be inheritable, we use a     */
     /* security attribute                                               */
+    HANDLE                nul_read, nul_write;
     HANDLE                pipe_read, pipe_write;
     HANDLE                stdout_handle, stderr_handle;
     SECURITY_ATTRIBUTES   sa;
@@ -564,10 +565,40 @@
     sa.lpSecurityDescriptor = NULL;
     sa.bInheritHandle = TRUE;
 
+    /* Redirect stdin and stderr to Windows /dev/null. If we instead pass our
+     * stdin/stderr handles and they are console handles, when the adb server
+     * starts up, the C Runtime will see console handles for a process that
+     * isn't connected to a console and it will configure stderr to be closed.
+     * At that point, freopen() could be used to reopen stderr, but it would
+     * take more massaging to fixup the file descriptor number that freopen()
+     * uses. It's simplest to avoid all of this complexity by just redirecting
+     * stdin/stderr to `nul' and then the C Runtime acts as expected.
+     */
+    nul_read = CreateFileW(L"nul", GENERIC_READ,
+                           FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
+                           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (nul_read == INVALID_HANDLE_VALUE) {
+        fprintf(stderr, "CreateFileW(nul, GENERIC_READ) failure, error %ld\n",
+                GetLastError());
+        return -1;
+    }
+
+    nul_write = CreateFileW(L"nul", GENERIC_WRITE,
+                            FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
+                            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (nul_write == INVALID_HANDLE_VALUE) {
+        fprintf(stderr, "CreateFileW(nul, GENERIC_WRITE) failure, error %ld\n",
+                GetLastError());
+        CloseHandle(nul_read);
+        return -1;
+    }
+
     /* create pipe, and ensure its read handle isn't inheritable */
     ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
     if (!ret) {
         fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
+        CloseHandle(nul_read);
+        CloseHandle(nul_write);
         return -1;
     }
 
@@ -595,9 +626,9 @@
 
     ZeroMemory( &startup, sizeof(startup) );
     startup.cb = sizeof(startup);
-    startup.hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
+    startup.hStdInput  = nul_read;
     startup.hStdOutput = pipe_write;
-    startup.hStdError  = GetStdHandle( STD_ERROR_HANDLE );
+    startup.hStdError  = nul_write;
     startup.dwFlags    = STARTF_USESTDHANDLES;
 
     ZeroMemory( &pinfo, sizeof(pinfo) );
@@ -620,6 +651,8 @@
             &startup,                 /* startup info, i.e. std handles */
             &pinfo );
 
+    CloseHandle( nul_read );
+    CloseHandle( nul_write );
     CloseHandle( pipe_write );
 
     if (!ret) {
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index 0cd6670..c018b8a 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -110,7 +110,7 @@
     int fd = unix_open(kNullFileName, O_RDONLY);
     CHECK_NE(fd, -1);
     dup2(fd, STDIN_FILENO);
-    adb_close(fd);
+    unix_close(fd);
 }
 
 static void setup_daemon_logging(void) {
@@ -121,7 +121,13 @@
     }
     dup2(fd, STDOUT_FILENO);
     dup2(fd, STDERR_FILENO);
-    adb_close(fd);
+    unix_close(fd);
+
+#ifdef _WIN32
+    // On Windows, stderr is buffered by default, so switch to non-buffered
+    // to match Linux.
+    setvbuf(stderr, NULL, _IONBF, 0);
+#endif
     fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
 }
 
@@ -153,7 +159,15 @@
         // Inform our parent that we are up and running.
         // TODO(danalbert): Can't use SendOkay because we're sending "OK\n", not
         // "OKAY".
-        // TODO(danalbert): Why do we use stdout for Windows?
+        // TODO(danalbert): Why do we use stdout for Windows? There is a
+        // comment in launch_server() that suggests that non-Windows uses
+        // stderr because it is non-buffered. So perhaps the history is that
+        // stdout was preferred for all platforms, but it was discovered that
+        // non-Windows needed a non-buffered fd, so stderr was used there.
+        // Note that using stderr on unix means that if you do
+        // `ADB_TRACE=all adb start-server`, it will say "ADB server didn't ACK"
+        // and "* failed to start daemon *" because the adb server will write
+        // logging to stderr, obscuring the OK\n output that is sent to stderr.
 #if defined(_WIN32)
         int reply_fd = STDOUT_FILENO;
         // Change stdout mode to binary so \n => \r\n translation does not
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index 7fbca31..4adac37 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -110,7 +110,6 @@
         "                                 ('-a' means copy timestamp and mode)\n"
         "  adb sync [ <directory> ]     - copy host->device only if changed\n"
         "                                 (-l means list but don't copy)\n"
-        "                                 (see 'adb help all')\n"
         "  adb shell                    - run remote shell interactively\n"
         "  adb shell <command>          - run remote shell command\n"
         "  adb emu <command>            - run emulator console command\n"
@@ -202,11 +201,12 @@
         "  adb reboot sideload          - reboots the device into the sideload mode in recovery program (adb root required).\n"
         "  adb reboot sideload-auto-reboot\n"
         "                               - reboots into the sideload mode, then reboots automatically after the sideload regardless of the result.\n"
-        "  adb reboot-bootloader        - reboots the device into the bootloader\n"
+        "  adb sideload <file>          - sideloads the given package\n"
         "  adb root                     - restarts the adbd daemon with root permissions\n"
         "  adb unroot                   - restarts the adbd daemon without root permissions\n"
         "  adb usb                      - restarts the adbd daemon listening on USB\n"
         "  adb tcpip <port>             - restarts the adbd daemon listening on TCP on the specified port\n"
+        "\n"
         "networking:\n"
         "  adb ppp <tty> [parameters]   - Run PPP over USB.\n"
         " Note: you should not automatically start a PPP connection.\n"
@@ -221,7 +221,7 @@
         "  - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n"
         "    is updated.\n"
         "\n"
-        "environmental variables:\n"
+        "environment variables:\n"
         "  ADB_TRACE                    - Print debug information. A comma separated list of the following values\n"
         "                                 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
         "  ANDROID_SERIAL               - The serial number to connect to. -s takes priority over this if given.\n"
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index 78ab3f6..d7fa362 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -171,7 +171,7 @@
 
         D("Local port disabled\n");
     } else {
-        if ((root_seclabel != nullptr) && (is_selinux_enabled() > 0)) {
+        if (root_seclabel != nullptr) {
             if (setcon(root_seclabel) < 0) {
                 LOG(FATAL) << "Could not set selinux context";
             }
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index b84a4e5..26d6389 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -134,8 +134,6 @@
   return fields == 7 ? 0 : -1;
 }
 
-static int selinux_enabled;
-
 /*
  * Corresponds with debugger_action_t enum type in
  * include/cutils/debugger.h.
@@ -153,9 +151,6 @@
   const char *perm;
   bool allowed = false;
 
-  if (selinux_enabled <= 0)
-    return true;
-
   if (action <= 0 || action >= (sizeof(debuggerd_perms)/sizeof(debuggerd_perms[0]))) {
     ALOGE("SELinux:  No permission defined for debugger action %d", action);
     return false;
@@ -589,7 +584,6 @@
 int main(int argc, char** argv) {
   union selinux_callback cb;
   if (argc == 1) {
-    selinux_enabled = is_selinux_enabled();
     cb.func_log = selinux_log_callback;
     selinux_set_callback(SELINUX_CB_LOG, cb);
     return do_server();
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 0de1def..4c4c95b 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -275,52 +275,52 @@
             "usage: fastboot [ <option> ] <command>\n"
             "\n"
             "commands:\n"
-            "  update <filename>                        reflash device from update.zip\n"
-            "  flashall                                 flash boot, system, vendor and if found,\n"
-            "                                           recovery\n"
-            "  flash <partition> [ <filename> ]         write a file to a flash partition\n"
-            "  flashing lock                            locks the device. Prevents flashing"
-            "                                           partitions\n"
-            "  flashing unlock                          unlocks the device. Allows user to"
-            "                                           flash any partition except the ones"
-            "                                           that are related to bootloader\n"
-            "  flashing lock_critical                   Prevents flashing bootloader related"
-            "                                           partitions\n"
-            "  flashing unlock_critical                 Enables flashing bootloader related"
-            "                                           partitions\n"
-            "  flashing get_unlock_ability              Queries bootloader to see if the"
-            "                                           device is unlocked\n"
-            "  erase <partition>                        erase a flash partition\n"
-            "  format[:[<fs type>][:[<size>]] <partition> format a flash partition.\n"
-            "                                           Can override the fs type and/or\n"
-            "                                           size the bootloader reports.\n"
-            "  getvar <variable>                        display a bootloader variable\n"
-            "  boot <kernel> [ <ramdisk> [ <second> ] ] download and boot kernel\n"
-            "  flash:raw boot <kernel> [ <ramdisk> [ <second> ] ] create bootimage and \n"
-            "                                           flash it\n"
-            "  devices                                  list all connected devices\n"
-            "  continue                                 continue with autoboot\n"
-            "  reboot [bootloader]                      reboot device, optionally into bootloader\n"
-            "  reboot-bootloader                        reboot device into bootloader\n"
-            "  help                                     show this help message\n"
+            "  update <filename>                        Reflash device from update.zip.\n"
+            "  flashall                                 Flash boot, system, vendor, and --\n"
+            "                                           if found -- recovery.\n"
+            "  flash <partition> [ <filename> ]         Write a file to a flash partition.\n"
+            "  flashing lock                            Locks the device. Prevents flashing.\n"
+            "  flashing unlock                          Unlocks the device. Allows flashing\n"
+            "                                           any partition except\n"
+            "                                           bootloader-related partitions.\n"
+            "  flashing lock_critical                   Prevents flashing bootloader-related\n"
+            "                                           partitions.\n"
+            "  flashing unlock_critical                 Enables flashing bootloader-related\n"
+            "                                           partitions.\n"
+            "  flashing get_unlock_ability              Queries bootloader to see if the\n"
+            "                                           device is unlocked.\n"
+            "  erase <partition>                        Erase a flash partition.\n"
+            "  format[:[<fs type>][:[<size>]] <partition>\n"
+            "                                           Format a flash partition. Can\n"
+            "                                           override the fs type and/or size\n"
+            "                                           the bootloader reports.\n"
+            "  getvar <variable>                        Display a bootloader variable.\n"
+            "  boot <kernel> [ <ramdisk> [ <second> ] ] Download and boot kernel.\n"
+            "  flash:raw boot <kernel> [ <ramdisk> [ <second> ] ]\n"
+            "                                           Create bootimage and flash it.\n"
+            "  devices [-l]                             List all connected devices [with\n"
+            "                                           device paths].\n"
+            "  continue                                 Continue with autoboot.\n"
+            "  reboot [bootloader]                      Reboot device [into bootloader].\n"
+            "  reboot-bootloader                        Reboot device into bootloader.\n"
+            "  help                                     Show this help message.\n"
             "\n"
             "options:\n"
-            "  -w                                       erase userdata and cache (and format\n"
-            "                                           if supported by partition type)\n"
-            "  -u                                       do not first erase partition before\n"
-            "                                           formatting\n"
-            "  -s <specific device>                     specify device serial number\n"
-            "                                           or path to device port\n"
-            "  -l                                       with \"devices\", lists device paths\n"
-            "  -p <product>                             specify product name\n"
-            "  -c <cmdline>                             override kernel commandline\n"
-            "  -i <vendor id>                           specify a custom USB vendor id\n"
-            "  -b <base_addr>                           specify a custom kernel base address.\n"
-            "                                           default: 0x10000000\n"
-            "  -n <page size>                           specify the nand page size.\n"
-            "                                           default: 2048\n"
-            "  -S <size>[K|M|G]                         automatically sparse files greater\n"
-            "                                           than size.  0 to disable\n"
+            "  -w                                       Erase userdata and cache (and format\n"
+            "                                           if supported by partition type).\n"
+            "  -u                                       Do not erase partition before\n"
+            "                                           formatting.\n"
+            "  -s <specific device>                     Specify device serial number\n"
+            "                                           or path to device port.\n"
+            "  -p <product>                             Specify product name.\n"
+            "  -c <cmdline>                             Override kernel commandline.\n"
+            "  -i <vendor id>                           Specify a custom USB vendor id.\n"
+            "  -b <base_addr>                           Specify a custom kernel base\n"
+            "                                           address (default: 0x10000000).\n"
+            "  -n <page size>                           Specify the nand page size\n"
+            "                                           (default: 2048).\n"
+            "  -S <size>[K|M|G]                         Automatically sparse files greater\n"
+            "                                           than 'size'. 0 to disable.\n"
         );
 }
 
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index bb2bed2..42f25c7 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -95,7 +95,7 @@
     int status;
     int ret;
     long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
-    char *tmpmnt_opts = "nomblk_io_submit,errors=remount-ro";
+    char tmpmnt_opts[64] = "errors=remount-ro";
     char *e2fsck_argv[] = {
         E2FSCK_BIN,
         "-y",
@@ -118,6 +118,10 @@
          * fix the filesystem.
          */
         errno = 0;
+        if (!strcmp(fs_type, "ext4")) {
+            // This option is only valid with ext4
+            strlcat(tmpmnt_opts, ",nomblk_io_submit", sizeof(tmpmnt_opts));
+        }
         ret = mount(blk_device, target, fs_type, tmpmnt_flags, tmpmnt_opts);
         INFO("%s(): mount(%s,%s,%s)=%d: %s\n",
              __func__, blk_device, target, fs_type, ret, strerror(errno));
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index 81c7c9a..0a945a3 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -767,8 +767,24 @@
 
 static int load_verity_state(struct fstab_rec *fstab, int *mode)
 {
-    off64_t offset = 0;
+    char propbuf[PROPERTY_VALUE_MAX];
     int match = 0;
+    off64_t offset = 0;
+
+    /* use the kernel parameter if set */
+    property_get("ro.boot.veritymode", propbuf, "");
+
+    if (*propbuf != '\0') {
+        if (!strcmp(propbuf, "enforcing")) {
+            *mode = VERITY_MODE_DEFAULT;
+            return 0;
+        } else if (!strcmp(propbuf, "logging")) {
+            *mode = VERITY_MODE_LOGGING;
+            return 0;
+        } else {
+            INFO("Unknown value %s for veritymode; ignoring", propbuf);
+        }
+    }
 
     if (get_verity_state_offset(fstab, &offset) < 0) {
         /* fall back to stateless behavior */
@@ -855,6 +871,13 @@
     struct dm_ioctl *io = (struct dm_ioctl *) buffer;
     struct fstab *fstab = NULL;
 
+    /* check if we need to store the state */
+    property_get("ro.boot.veritymode", propbuf, "");
+
+    if (*propbuf != '\0') {
+        return 0; /* state is kept by the bootloader */
+    }
+
     fd = TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC));
 
     if (fd == -1) {
diff --git a/init/Android.mk b/init/Android.mk
index b14f9b5..45b002d 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -18,8 +18,6 @@
     -Wno-unused-parameter \
     -Werror \
 
-init_clang := true
-
 # --
 
 include $(CLEAR_VARS)
@@ -32,7 +30,7 @@
 
 LOCAL_STATIC_LIBRARIES := libbase
 LOCAL_MODULE := libinit
-LOCAL_CLANG := $(init_clang)
+LOCAL_CLANG := true
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -79,7 +77,7 @@
     ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \
     ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdogd
 
-LOCAL_CLANG := $(init_clang)
+LOCAL_CLANG := true
 include $(BUILD_EXECUTABLE)
 
 
@@ -96,5 +94,5 @@
     libbase \
 
 LOCAL_STATIC_LIBRARIES := libinit
-LOCAL_CLANG := $(init_clang)
+LOCAL_CLANG := true
 include $(BUILD_NATIVE_TEST)
diff --git a/init/devices.cpp b/init/devices.cpp
index 2c7f5a9..3652c57 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -241,10 +241,8 @@
 
     mode = get_device_perm(path, links, &uid, &gid) | (block ? S_IFBLK : S_IFCHR);
 
-    if (sehandle) {
-        selabel_lookup_best_match(sehandle, &secontext, path, links, mode);
-        setfscreatecon(secontext);
-    }
+    selabel_lookup_best_match(sehandle, &secontext, path, links, mode);
+    setfscreatecon(secontext);
 
     dev = makedev(major, minor);
     /* Temporarily change egid to avoid race condition setting the gid of the
@@ -907,7 +905,7 @@
         struct uevent uevent;
         parse_event(msg, &uevent);
 
-        if (sehandle && selinux_status_updated() > 0) {
+        if (selinux_status_updated() > 0) {
             struct selabel_handle *sehandle2;
             sehandle2 = selinux_android_file_context_handle();
             if (sehandle2) {
@@ -974,11 +972,8 @@
 }
 
 void device_init() {
-    sehandle = NULL;
-    if (is_selinux_enabled() > 0) {
-        sehandle = selinux_android_file_context_handle();
-        selinux_status_open(true);
-    }
+    sehandle = selinux_android_file_context_handle();
+    selinux_status_open(true);
 
     /* is 256K enough? udev uses 16MB! */
     device_fd = uevent_open_socket(256*1024, true);
diff --git a/init/init.cpp b/init/init.cpp
index 2500985..8ea60dd 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -220,40 +220,38 @@
     }
 
     char* scon = NULL;
-    if (is_selinux_enabled() > 0) {
-        if (svc->seclabel) {
-            scon = strdup(svc->seclabel);
-            if (!scon) {
-                ERROR("Out of memory while starting '%s'\n", svc->name);
-                return;
-            }
-        } else {
-            char *mycon = NULL, *fcon = NULL;
+    if (svc->seclabel) {
+        scon = strdup(svc->seclabel);
+        if (!scon) {
+            ERROR("Out of memory while starting '%s'\n", svc->name);
+            return;
+        }
+    } else {
+        char *mycon = NULL, *fcon = NULL;
 
-            INFO("computing context for service '%s'\n", svc->args[0]);
-            int rc = getcon(&mycon);
-            if (rc < 0) {
-                ERROR("could not get context while starting '%s'\n", svc->name);
-                return;
-            }
+        INFO("computing context for service '%s'\n", svc->args[0]);
+        int rc = getcon(&mycon);
+        if (rc < 0) {
+            ERROR("could not get context while starting '%s'\n", svc->name);
+            return;
+        }
 
-            rc = getfilecon(svc->args[0], &fcon);
-            if (rc < 0) {
-                ERROR("could not get context while starting '%s'\n", svc->name);
-                freecon(mycon);
-                return;
-            }
-
-            rc = security_compute_create(mycon, fcon, string_to_security_class("process"), &scon);
-            if (rc == 0 && !strcmp(scon, mycon)) {
-                ERROR("Warning!  Service %s needs a SELinux domain defined; please fix!\n", svc->name);
-            }
+        rc = getfilecon(svc->args[0], &fcon);
+        if (rc < 0) {
+            ERROR("could not get context while starting '%s'\n", svc->name);
             freecon(mycon);
-            freecon(fcon);
-            if (rc < 0) {
-                ERROR("could not get context while starting '%s'\n", svc->name);
-                return;
-            }
+            return;
+        }
+
+        rc = security_compute_create(mycon, fcon, string_to_security_class("process"), &scon);
+        if (rc == 0 && !strcmp(scon, mycon)) {
+            ERROR("Warning!  Service %s needs a SELinux domain defined; please fix!\n", svc->name);
+        }
+        freecon(mycon);
+        freecon(fcon);
+        if (rc < 0) {
+            ERROR("could not get context while starting '%s'\n", svc->name);
+            return;
         }
     }
 
@@ -335,7 +333,7 @@
             }
         }
         if (svc->seclabel) {
-            if (is_selinux_enabled() > 0 && setexeccon(svc->seclabel) < 0) {
+            if (setexeccon(svc->seclabel) < 0) {
                 ERROR("cannot setexeccon('%s'): %s\n", svc->seclabel, strerror(errno));
                 _exit(127);
             }
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 0ee0351..5b7a1cb 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -92,9 +92,6 @@
 
 static int check_mac_perms(const char *name, char *sctx)
 {
-    if (is_selinux_enabled() <= 0)
-        return 1;
-
     char *tctx = NULL;
     int result = 0;
 
diff --git a/libbacktrace/BacktracePtrace.cpp b/libbacktrace/BacktracePtrace.cpp
index e10cce1..fd8b713 100644
--- a/libbacktrace/BacktracePtrace.cpp
+++ b/libbacktrace/BacktracePtrace.cpp
@@ -37,8 +37,6 @@
   errno = 0;
   *out_value = ptrace(PTRACE_PEEKTEXT, tid, reinterpret_cast<void*>(addr), nullptr);
   if (*out_value == static_cast<word_t>(-1) && errno) {
-    BACK_LOGW("invalid pointer %p reading from tid %d, ptrace() strerror(errno)=%s",
-              reinterpret_cast<void*>(addr), tid, strerror(errno));
     return false;
   }
   return true;
diff --git a/liblog/Android.mk b/liblog/Android.mk
index d7766f5..ce282bd 100644
--- a/liblog/Android.mk
+++ b/liblog/Android.mk
@@ -68,6 +68,7 @@
 LOCAL_LDLIBS := -lrt
 endif
 LOCAL_MULTILIB := both
+LOCAL_CXX_STL := none
 include $(BUILD_HOST_SHARED_LIBRARY)
 
 
@@ -77,6 +78,8 @@
 LOCAL_MODULE := liblog
 LOCAL_SRC_FILES := $(liblog_target_sources)
 LOCAL_CFLAGS := -Werror $(liblog_cflags)
+# AddressSanitizer runtime library depends on liblog.
+LOCAL_SANITIZE := never
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -87,6 +90,9 @@
 # TODO: This is to work around b/19059885. Remove after root cause is fixed
 LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
 
+LOCAL_SANITIZE := never
+LOCAL_CXX_STL := none
+
 include $(BUILD_SHARED_LIBRARY)
 
 include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/libutils/Android.mk b/libutils/Android.mk
index e9c5f89..8f829f3 100644
--- a/libutils/Android.mk
+++ b/libutils/Android.mk
@@ -91,7 +91,7 @@
         liblog \
         libdl
 
-LOCAL_MODULE:= libutils
+LOCAL_MODULE := libutils
 include $(BUILD_STATIC_LIBRARY)
 
 # For the device, shared
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 736e02e..e598bb8 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -14,6 +14,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/cdefs.h>
+#include <sys/resource.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -33,6 +34,7 @@
 #include <log/logd.h>
 #include <log/logger.h>
 #include <log/logprint.h>
+#include <utils/threads.h>
 
 #define DEFAULT_MAX_ROTATED_LOGS 4
 
@@ -221,6 +223,10 @@
             fprintf(stderr, "failed to set to batch scheduler\n");
         }
 
+        if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) {
+            fprintf(stderr, "failed set to priority\n");
+        }
+
         g_outFD = openLogFile (g_outputFileName);
 
         if (g_outFD < 0) {
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
index 8df0d0a..7d14648 100644
--- a/logd/LogKlog.cpp
+++ b/logd/LogKlog.cpp
@@ -36,6 +36,140 @@
 
 static const char priority_message[] = { KMSG_PRIORITY(LOG_INFO), '\0' };
 
+// Parsing is hard
+
+// called if we see a '<', s is the next character, returns pointer after '>'
+static char *is_prio(char *s) {
+    if (!isdigit(*s++)) {
+        return NULL;
+    }
+    char c;
+    while ((c = *s++)) {
+        if (!isdigit(c) && (c == '>')) {
+            return s;
+        }
+    }
+    return NULL;
+}
+
+// called if we see a '[', s is the next character, returns pointer after ']'
+static char *is_timestamp(char *s) {
+    while (*s == ' ') {
+        ++s;
+    }
+    if (!isdigit(*s++)) {
+        return NULL;
+    }
+    bool first_period = true;
+    char c;
+    while ((c = *s++)) {
+        if ((c == '.') && first_period) {
+            first_period = false;
+            continue;
+        }
+        if (!isdigit(c) && (c == ']')) {
+            return s;
+        }
+    }
+    return NULL;
+}
+
+// Like strtok_r with "\r\n" except that we look for log signatures (regex)
+//   \(\(<[0-9]+>\)\([[] *[0-9]+[]]\)\{0,1\}\|[[] *[0-9]+[]]\)
+// and split if we see a second one without a newline.
+
+#define SIGNATURE_MASK     0xF0
+// <digit> following ('0' to '9' masked with ~SIGNATURE_MASK) added to signature
+#define LESS_THAN_SIG      SIGNATURE_MASK
+#define OPEN_BRACKET_SIG   ((SIGNATURE_MASK << 1) & SIGNATURE_MASK)
+// space is one more than <digit> of 9
+#define OPEN_BRACKET_SPACE ((char)(OPEN_BRACKET_SIG | 10))
+
+char *log_strtok_r(char *s, char **last) {
+    if (!s) {
+        if (!(s = *last)) {
+            return NULL;
+        }
+        // fixup for log signature split <,
+        // LESS_THAN_SIG + <digit>
+        if ((*s & SIGNATURE_MASK) == LESS_THAN_SIG) {
+            *s = (*s & ~SIGNATURE_MASK) + '0';
+            *--s = '<';
+        }
+        // fixup for log signature split [,
+        // OPEN_BRACKET_SPACE is space, OPEN_BRACKET_SIG + <digit>
+        if ((*s & SIGNATURE_MASK) == OPEN_BRACKET_SIG) {
+            if (*s == OPEN_BRACKET_SPACE) {
+                *s = ' ';
+            } else {
+                *s = (*s & ~SIGNATURE_MASK) + '0';
+            }
+            *--s = '[';
+        }
+    }
+
+    s += strspn(s, "\r\n");
+
+    if (!*s) { // no non-delimiter characters
+        *last = NULL;
+        return NULL;
+    }
+    char *peek, *tok = s;
+
+    for (;;) {
+        char c = *s++;
+        switch (c) {
+        case '\0':
+            *last = NULL;
+            return tok;
+
+        case '\r':
+        case '\n':
+            s[-1] = '\0';
+            *last = s;
+            return tok;
+
+        case '<':
+            peek = is_prio(s);
+            if (!peek) {
+                break;
+            }
+            if (s != (tok + 1)) { // not first?
+                s[-1] = '\0';
+                *s &= ~SIGNATURE_MASK;
+                *s |= LESS_THAN_SIG; // signature for '<'
+                *last = s;
+                return tok;
+            }
+            s = peek;
+            if ((*s == '[') && ((peek = is_timestamp(s + 1)))) {
+                s = peek;
+            }
+            break;
+
+        case '[':
+            peek = is_timestamp(s);
+            if (!peek) {
+                break;
+            }
+            if (s != (tok + 1)) { // not first?
+                s[-1] = '\0';
+                if (*s == ' ') {
+                    *s = OPEN_BRACKET_SPACE;
+                } else {
+                    *s &= ~SIGNATURE_MASK;
+                    *s |= OPEN_BRACKET_SIG; // signature for '['
+                }
+                *last = s;
+                return tok;
+            }
+            s = peek;
+            break;
+        }
+    }
+    /* NOTREACHED */
+}
+
 log_time LogKlog::correction = log_time(CLOCK_REALTIME) - log_time(CLOCK_MONOTONIC);
 
 LogKlog::LogKlog(LogBuffer *buf, LogReader *reader, int fdWrite, int fdRead, bool auditd) :
@@ -81,8 +215,8 @@
         char *ep = buffer + len;
         *ep = '\0';
         len = 0;
-        for(char *ptr, *tok = buffer;
-                ((tok = strtok_r(tok, "\r\n", &ptr)));
+        for(char *ptr = NULL, *tok = buffer;
+                ((tok = log_strtok_r(tok, &ptr)));
                 tok = NULL) {
             if (((tok + strlen(tok)) == ep) && (retval != 0) && full) {
                 len = strlen(tok);
diff --git a/logd/LogKlog.h b/logd/LogKlog.h
index 8de9c87..a898c63 100644
--- a/logd/LogKlog.h
+++ b/logd/LogKlog.h
@@ -21,6 +21,8 @@
 #include <log/log_read.h>
 #include "LogReader.h"
 
+char *log_strtok_r(char *str, char **saveptr);
+
 class LogKlog : public SocketListener {
     LogBuffer *logbuf;
     LogReader *reader;
diff --git a/logd/main.cpp b/logd/main.cpp
index 6db819e..a876c99 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -27,6 +27,7 @@
 #include <sys/capability.h>
 #include <sys/klog.h>
 #include <sys/prctl.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <syslog.h>
@@ -37,6 +38,7 @@
 #include <cutils/sockets.h>
 #include <log/event_tag_map.h>
 #include <private/android_filesystem_config.h>
+#include <utils/threads.h>
 
 #include "CommandListener.h"
 #include "LogBuffer.h"
@@ -91,6 +93,10 @@
         return -1;
     }
 
+    if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) {
+        return -1;
+    }
+
     if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
         return -1;
     }
@@ -156,6 +162,7 @@
 static void *reinit_thread_start(void * /*obj*/) {
     prctl(PR_SET_NAME, "logd.daemon");
     set_sched_policy(0, SP_BACKGROUND);
+    setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND);
 
     setgid(AID_SYSTEM);
     setuid(AID_SYSTEM);
@@ -417,8 +424,8 @@
                 kl->synchronize(buf);
             }
 
-            for (char *ptr, *tok = buf;
-                 (rc >= 0) && ((tok = strtok_r(tok, "\r\n", &ptr)));
+            for (char *ptr = NULL, *tok = buf;
+                 (rc >= 0) && ((tok = log_strtok_r(tok, &ptr)));
                  tok = NULL) {
                 if (al) {
                     rc = al->log(tok);
diff --git a/rootdir/init.rc b/rootdir/init.rc
index b5b74ea..72df0f5 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -194,9 +194,9 @@
     # We restorecon /cache in case the cache partition has been reset.
     restorecon_recursive /cache
 
-    # This may have been created by the recovery system with odd permissions
-    chown system cache /cache/recovery
-    chmod 0770 /cache/recovery
+    # Create /cache/recovery in case it's not there. It'll also fix the odd
+    # permissions if created by the recovery system.
+    mkdir /cache/recovery 0770 system cache
 
     #change permissions on vmallocinfo so we can grab it from bugreports
     chown root log /proc/vmallocinfo
@@ -640,7 +640,12 @@
     disabled
     oneshot
 
-service pre-recovery /system/bin/uncrypt
+service uncrypt /system/bin/uncrypt
+    class main
+    disabled
+    oneshot
+
+service pre-recovery /system/bin/uncrypt --reboot
     class main
     disabled
     oneshot
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index fc38907..273b263 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -46,7 +46,6 @@
     log \
     ls \
     lsof \
-    mount \
     nandread \
     newfs_msdos \
     ps \
diff --git a/toolbox/mount.c b/toolbox/mount.c
deleted file mode 100644
index 66ae8b1..0000000
--- a/toolbox/mount.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * mount.c, by rmk
- */
-
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <linux/loop.h>
-
-#define ARRAY_SIZE(x)	(sizeof(x) / sizeof(x[0]))
-
-#define DEFAULT_LOOP_DEVICE "/dev/block/loop0"
-#define LOOPDEV_MAXLEN 64
-
-struct mount_opts {
-	const char str[16];
-	unsigned long rwmask;
-	unsigned long rwset;
-	unsigned long rwnoset;
-};
-
-struct extra_opts {
-	char *str;
-	char *end;
-	int used_size;
-	int alloc_size;
-};
-
-/*
- * These options define the function of "mount(2)".
- */
-#define MS_TYPE	(MS_REMOUNT|MS_BIND|MS_MOVE)
-
-
-static const struct mount_opts options[] = {
-	/* name		mask		set		noset		*/
-	{ "async",	MS_SYNCHRONOUS,	0,		MS_SYNCHRONOUS	},
-	{ "atime",	MS_NOATIME,	0,		MS_NOATIME	},
-	{ "bind",	MS_TYPE,	MS_BIND,	0,		},
-	{ "dev",	MS_NODEV,	0,		MS_NODEV	},
-	{ "diratime",	MS_NODIRATIME,	0,		MS_NODIRATIME	},
-	{ "dirsync",	MS_DIRSYNC,	MS_DIRSYNC,	0		},
-	{ "exec",	MS_NOEXEC,	0,		MS_NOEXEC	},
-	{ "move",	MS_TYPE,	MS_MOVE,	0		},
-	{ "recurse",	MS_REC,		MS_REC,		0		},
-	{ "rec",	MS_REC,		MS_REC,		0		},
-	{ "remount",	MS_TYPE,	MS_REMOUNT,	0		},
-	{ "ro",		MS_RDONLY,	MS_RDONLY,	0		},
-	{ "rw",		MS_RDONLY,	0,		MS_RDONLY	},
-	{ "suid",	MS_NOSUID,	0,		MS_NOSUID	},
-	{ "sync",	MS_SYNCHRONOUS,	MS_SYNCHRONOUS,	0		},
-	{ "verbose",	MS_VERBOSE,	MS_VERBOSE,	0		},
-	{ "unbindable",	MS_UNBINDABLE,	MS_UNBINDABLE,	0		},
-	{ "private",	MS_PRIVATE,	MS_PRIVATE,	0		},
-	{ "slave",	MS_SLAVE,	MS_SLAVE,	0		},
-	{ "shared",	MS_SHARED,	MS_SHARED,	0		},
-};
-
-static void add_extra_option(struct extra_opts *extra, char *s)
-{
-	int len = strlen(s);
-	int newlen;
-
-	if (extra->str)
-	       len++;			/* +1 for ',' */
-	newlen = extra->used_size + len;
-
-	if (newlen >= extra->alloc_size) {
-		char *new;
-
-		new = realloc(extra->str, newlen + 1);	/* +1 for NUL */
-		if (!new)
-			return;
-
-		extra->str = new;
-		extra->end = extra->str + extra->used_size;
-		extra->alloc_size = newlen + 1;
-	}
-
-	if (extra->used_size) {
-		*extra->end = ',';
-		extra->end++;
-	}
-	strcpy(extra->end, s);
-	extra->used_size += len;
-
-}
-
-static unsigned long
-parse_mount_options(char *arg, unsigned long rwflag, struct extra_opts *extra, int* loop, char *loopdev)
-{
-	char *s;
-    
-    *loop = 0;
-	while ((s = strsep(&arg, ",")) != NULL) {
-		char *opt = s;
-		unsigned int i;
-		int res, no = s[0] == 'n' && s[1] == 'o';
-
-		if (no)
-			s += 2;
-
-        if (strncmp(s, "loop=", 5) == 0) {
-            *loop = 1;
-            strlcpy(loopdev, s + 5, LOOPDEV_MAXLEN);
-            continue;
-        }
-
-        if (strcmp(s, "loop") == 0) {
-            *loop = 1;
-            strlcpy(loopdev, DEFAULT_LOOP_DEVICE, LOOPDEV_MAXLEN);
-            continue;
-        }
-		for (i = 0, res = 1; i < ARRAY_SIZE(options); i++) {
-			res = strcmp(s, options[i].str);
-
-			if (res == 0) {
-				rwflag &= ~options[i].rwmask;
-				if (no)
-					rwflag |= options[i].rwnoset;
-				else
-					rwflag |= options[i].rwset;
-			}
-			if (res <= 0)
-				break;
-		}
-
-		if (res != 0 && s[0])
-			add_extra_option(extra, opt);
-	}
-
-	return rwflag;
-}
-
-/*
- * Mark the given block device as read-write, using the BLKROSET ioctl.
- */
-static void fs_set_blk_rw(const char *blockdev)
-{
-    int fd;
-    int OFF = 0;
-
-    fd = open(blockdev, O_RDONLY);
-    if (fd < 0) {
-        // should never happen
-        return;
-    }
-
-    ioctl(fd, BLKROSET, &OFF);
-    close(fd);
-}
-
-static char *progname;
-
-static struct extra_opts extra;
-static unsigned long rwflag;
-
-static int
-do_mount(char *dev, char *dir, char *type, unsigned long rwflag, void *data, int loop,
-         char *loopdev)
-{
-	char *s;
-	int error = 0;
-
-    if (loop) {
-        int file_fd, device_fd;
-        int flags;
-
-        flags = (rwflag & MS_RDONLY) ? O_RDONLY : O_RDWR;
-        
-        file_fd = open(dev, flags);
-        if (file_fd < 0) {
-            perror("open backing file failed");
-            return 1;
-        }
-        device_fd = open(loopdev, flags);
-        if (device_fd < 0) {
-            perror("open loop device failed");
-            close(file_fd);
-            return 1;
-        }
-        if (ioctl(device_fd, LOOP_SET_FD, file_fd) < 0) {
-            perror("ioctl LOOP_SET_FD failed");
-            close(file_fd);
-            close(device_fd);
-            return 1;
-        }
-
-        close(file_fd);
-        close(device_fd);
-        dev = loopdev;
-    }
-
-    if ((rwflag & MS_RDONLY) == 0) {
-        fs_set_blk_rw(dev);
-    }
-
-	while ((s = strsep(&type, ",")) != NULL) {
-retry:
-		if (mount(dev, dir, s, rwflag, data) == -1) {
-			error = errno;
-			/*
-			 * If the filesystem is not found, or the
-			 * superblock is invalid, try the next.
-			 */
-			if (error == ENODEV || error == EINVAL)
-				continue;
-
-			/*
-			 * If we get EACCESS, and we're trying to
-			 * mount readwrite and this isn't a remount,
-			 * try read only.
-			 */
-			if (error == EACCES &&
-			    (rwflag & (MS_REMOUNT|MS_RDONLY)) == 0) {
-				rwflag |= MS_RDONLY;
-				goto retry;
-			}
-			break;
-		}
-	}
-
-	if (error) {
-		errno = error;
-		perror("mount");
-		return 255;
-	}
-
-	return 0;
-}
-
-static int print_mounts()
-{
-    FILE* f;
-    int length;
-    char buffer[100];
-    
-    f = fopen("/proc/mounts", "r");
-    if (!f) {
-        fprintf(stdout, "could not open /proc/mounts\n");
-        return -1;
-    }
-
-    do {
-        length = fread(buffer, 1, 100, f);
-        if (length > 0)
-            fwrite(buffer, 1, length, stdout);
-    } while (length > 0);
-
-    fclose(f);
-    return 0;
-}
-
-static int get_mounts_dev_dir(const char *arg, char **dev, char **dir)
-{
-	FILE *f;
-	char mount_dev[256];
-	char mount_dir[256];
-	char mount_type[256];
-	char mount_opts[256];
-	int mount_freq;
-	int mount_passno;
-	int match;
-
-	f = fopen("/proc/mounts", "r");
-	if (!f) {
-		fprintf(stdout, "could not open /proc/mounts\n");
-		return -1;
-	}
-
-	do {
-		match = fscanf(f, "%255s %255s %255s %255s %d %d\n",
-					   mount_dev, mount_dir, mount_type,
-					   mount_opts, &mount_freq, &mount_passno);
-		mount_dev[255] = 0;
-		mount_dir[255] = 0;
-		mount_type[255] = 0;
-		mount_opts[255] = 0;
-		if (match == 6 &&
-			(strcmp(arg, mount_dev) == 0 ||
-			 strcmp(arg, mount_dir) == 0)) {
-			*dev = strdup(mount_dev);
-			*dir = strdup(mount_dir);
-			fclose(f);
-			return 0;
-		}
-	} while (match != EOF);
-
-	fclose(f);
-	return -1;
-}
-
-int mount_main(int argc, char *argv[])
-{
-	char *type = NULL;
-	char *dev = NULL;
-	char *dir = NULL;
-	int c;
-	int loop = 0;
-	char loopdev[LOOPDEV_MAXLEN];
-
-	progname = argv[0];
-	rwflag = MS_VERBOSE;
-	
-	// mount with no arguments is equivalent to "cat /proc/mounts"
-	if (argc == 1) return print_mounts();
-
-	do {
-		c = getopt(argc, argv, "o:rt:w");
-		if (c == EOF)
-			break;
-		switch (c) {
-		case 'o':
-			rwflag = parse_mount_options(optarg, rwflag, &extra, &loop, loopdev);
-			break;
-		case 'r':
-			rwflag |= MS_RDONLY;
-			break;
-		case 't':
-			type = optarg;
-			break;
-		case 'w':
-			rwflag &= ~MS_RDONLY;
-			break;
-		case '?':
-			fprintf(stderr, "%s: invalid option -%c\n",
-				progname, optopt);
-			exit(1);
-		}
-	} while (1);
-
-	/*
-	 * If remount, bind or move was specified, then we don't
-	 * have a "type" as such.  Use the dummy "none" type.
-	 */
-	if (rwflag & MS_TYPE)
-		type = "none";
-
-	if (optind + 2 == argc) {
-		dev = argv[optind];
-		dir = argv[optind + 1];
-	} else if (optind + 1 == argc && rwflag & MS_REMOUNT) {
-		get_mounts_dev_dir(argv[optind], &dev, &dir);
-	}
-
-	if (dev == NULL || dir == NULL || type == NULL) {
-		fprintf(stderr, "Usage: %s [-r] [-w] [-o options] [-t type] "
-			"device directory\n", progname);
-		exit(1);
-	}
-
-	return do_mount(dev, dir, type, rwflag, extra.str, loop, loopdev);
-	/* We leak dev and dir in some cases, but we're about to exit */
-}