Merge "Allow inputflinger to have CAP_BLOCK_SUSPEND."
diff --git a/adb/Android.mk b/adb/Android.mk
index 8d38077..4f19d47 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -208,10 +208,11 @@
 LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
 LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
-LOCAL_C_INCLUDES += system/extras/ext4_utils system/core/fs_mgr/include
+LOCAL_C_INCLUDES += system/extras/ext4_utils
 
 LOCAL_STATIC_LIBRARIES := \
     libadbd \
+    libbase \
     libfs_mgr \
     liblog \
     libcutils \
diff --git a/adb/adb_main.cpp b/adb/adb_main.cpp
index a03fcf1..fb17e89 100644
--- a/adb/adb_main.cpp
+++ b/adb/adb_main.cpp
@@ -110,6 +110,13 @@
 #if defined(ALLOW_ADBD_ROOT)
     char value[PROPERTY_VALUE_MAX];
 
+    // The emulator is never secure, so don't drop privileges there.
+    // TODO: this seems like a bug --- shouldn't the emulator behave like a device?
+    property_get("ro.kernel.qemu", value, "");
+    if (strcmp(value, "1") == 0) {
+        return false;
+    }
+
     // The properties that affect `adb root` and `adb unroot` are ro.secure and
     // ro.debuggable. In this context the names don't make the expected behavior
     // particularly obvious.
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index c9b1eab..f9ca5ed 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -209,7 +209,11 @@
         "  adb get-devpath              - prints: <device-path>\n"
         "  adb status-window            - continuously print device status for a specified device\n"
         "  adb remount                  - remounts the /system, /vendor (if present) and /oem (if present) partitions on the device read-write\n"
-        "  adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
+        "  adb reboot [bootloader|recovery]\n"
+        "                               - reboots the device, optionally into the bootloader or recovery program.\n"
+        "  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 root                     - restarts the adbd daemon with root permissions\n"
         "  adb unroot                   - restarts the adbd daemon without root permissions\n"
@@ -245,13 +249,10 @@
 
 #if defined(_WIN32)
 
-// Windows does not have <termio.h>.
-static void stdin_raw_init(int fd) {
-
-}
-
-static void stdin_raw_restore(int fd) {
-
+// Implemented in sysdeps_win32.c.
+extern "C" {
+void stdin_raw_init(int fd);
+void stdin_raw_restore(int fd);
 }
 
 #else
@@ -1129,6 +1130,17 @@
     }
 }
 
+static int adb_connect_command(const char* command) {
+    int fd = adb_connect(command);
+    if (fd != -1) {
+        read_and_dump(fd);
+        adb_close(fd);
+        return 0;
+    }
+    fprintf(stderr, "Error: %s\n", adb_error());
+    return 1;
+}
+
 int adb_commandline(int argc, const char **argv)
 {
     char buf[4096];
@@ -1478,20 +1490,14 @@
              !strcmp(argv[0], "disable-verity") ||
              !strcmp(argv[0], "enable-verity")) {
         char command[100];
-        if (!strcmp(argv[0], "reboot-bootloader"))
+        if (!strcmp(argv[0], "reboot-bootloader")) {
             snprintf(command, sizeof(command), "reboot:bootloader");
-        else if (argc > 1)
+        } else if (argc > 1) {
             snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
-        else
+        } else {
             snprintf(command, sizeof(command), "%s:", argv[0]);
-        int fd = adb_connect(command);
-        if (fd >= 0) {
-            read_and_dump(fd);
-            adb_close(fd);
-            return 0;
         }
-        fprintf(stderr,"error: %s\n", adb_error());
-        return 1;
+        return adb_connect_command(command);
     }
     else if (!strcmp(argv[0], "bugreport")) {
         if (argc != 1) return usage();
@@ -1716,15 +1722,7 @@
         return adb_auth_keygen(argv[1]);
     }
     else if (!strcmp(argv[0], "jdwp")) {
-        int  fd = adb_connect("jdwp");
-        if (fd >= 0) {
-            read_and_dump(fd);
-            adb_close(fd);
-            return 0;
-        } else {
-            fprintf(stderr, "error: %s\n", adb_error());
-            return -1;
-        }
+        return adb_connect_command("jdwp");
     }
     /* "adb /?" is a common idiom under Windows */
     else if (!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
diff --git a/adb/services.cpp b/adb/services.cpp
index abf8ea5..12eb406 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -32,6 +32,7 @@
 #endif
 
 #if !ADB_HOST
+#include "base/file.h"
 #include "cutils/android_reboot.h"
 #include "cutils/properties.h"
 #endif
@@ -132,31 +133,72 @@
     adb_close(fd);
 }
 
-void reboot_service(int fd, void *arg)
-{
+static bool reboot_service_impl(int fd, const char* arg) {
+    const char* reboot_arg = arg;
+    bool auto_reboot = false;
+
+    if (strcmp(reboot_arg, "sideload-auto-reboot") == 0) {
+        auto_reboot = true;
+        reboot_arg = "sideload";
+    }
+
     char buf[100];
-    char property_val[PROPERTY_VALUE_MAX];
-    int ret;
+    // It reboots into sideload mode by setting "--sideload" or "--sideload_auto_reboot"
+    // in the command file.
+    if (strcmp(reboot_arg, "sideload") == 0) {
+        if (getuid() != 0) {
+            snprintf(buf, sizeof(buf), "'adb root' is required for 'adb reboot sideload'.\n");
+            WriteStringFully(fd, buf);
+            return false;
+        }
+
+        const char* const recovery_dir = "/cache/recovery";
+        const char* const command_file = "/cache/recovery/command";
+        // Ensure /cache/recovery exists.
+        if (adb_mkdir(recovery_dir, 0770) == -1 && errno != EEXIST) {
+            D("Failed to create directory '%s': %s\n", recovery_dir, strerror(errno));
+            return false;
+        }
+
+        bool write_status = android::base::WriteStringToFile(
+                auto_reboot ? "--sideload_auto_reboot" : "--sideload", command_file);
+        if (!write_status) {
+            return false;
+        }
+
+        reboot_arg = "recovery";
+    }
 
     sync();
 
-    ret = snprintf(property_val, sizeof(property_val), "reboot,%s", (char *) arg);
-    if (ret >= (int) sizeof(property_val)) {
+    char property_val[PROPERTY_VALUE_MAX];
+    int ret = snprintf(property_val, sizeof(property_val), "reboot,%s", reboot_arg);
+    if (ret >= static_cast<int>(sizeof(property_val))) {
         snprintf(buf, sizeof(buf), "reboot string too long. length=%d\n", ret);
-        WriteFdExactly(fd, buf, strlen(buf));
-        goto cleanup;
+        WriteStringFully(fd, buf);
+        return false;
     }
 
     ret = property_set(ANDROID_RB_PROPERTY, property_val);
     if (ret < 0) {
         snprintf(buf, sizeof(buf), "reboot failed: %d\n", ret);
-        WriteFdExactly(fd, buf, strlen(buf));
-        goto cleanup;
+        WriteStringFully(fd, buf);
+        return false;
     }
-    // Don't return early. Give the reboot command time to take effect
-    // to avoid messing up scripts which do "adb reboot && adb wait-for-device"
-    while(1) { pause(); }
-cleanup:
+
+    return true;
+}
+
+void reboot_service(int fd, void* arg)
+{
+    if (reboot_service_impl(fd, static_cast<const char*>(arg))) {
+        // Don't return early. Give the reboot command time to take effect
+        // to avoid messing up scripts which do "adb reboot && adb wait-for-device"
+        while (1) {
+            pause();
+        }
+    }
+
     free(arg);
     adb_close(fd);
 }
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index c317e3a..2ad28fa 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -150,10 +150,8 @@
 #undef   close
 #define  close   ____xxx_close
 
-static __inline__  int  unix_read(int  fd, void*  buf, size_t  len)
-{
-    return read(fd, buf, len);
-}
+extern int  unix_read(int  fd, void*  buf, size_t  len);
+
 #undef   read
 #define  read  ___xxx_read
 
diff --git a/adb/sysdeps_win32.c b/adb/sysdeps_win32.c
index c28e031..c2742f1 100644
--- a/adb/sysdeps_win32.c
+++ b/adb/sysdeps_win32.c
@@ -22,6 +22,7 @@
 #include <windows.h>
 
 #include <errno.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -2250,3 +2251,905 @@
 	}
 	/* NOTREACHED */
 }
+
+/**************************************************************************/
+/**************************************************************************/
+/*****                                                                *****/
+/*****      Console Window Terminal Emulation                         *****/
+/*****                                                                *****/
+/**************************************************************************/
+/**************************************************************************/
+
+// This reads input from a Win32 console window and translates it into Unix
+// terminal-style sequences. This emulates mostly Gnome Terminal (in Normal
+// mode, not Application mode), which itself emulates xterm. Gnome Terminal
+// is emulated instead of xterm because it is probably more popular than xterm:
+// Ubuntu's default Ctrl-Alt-T shortcut opens Gnome Terminal, Gnome Terminal
+// supports modern fonts, etc. It seems best to emulate the terminal that most
+// Android developers use because they'll fix apps (the shell, etc.) to keep
+// working with that terminal's emulation.
+//
+// The point of this emulation is not to be perfect or to solve all issues with
+// console windows on Windows, but to be better than the original code which
+// just called read() (which called ReadFile(), which called ReadConsoleA())
+// which did not support Ctrl-C, tab completion, shell input line editing
+// keys, server echo, and more.
+//
+// This implementation reconfigures the console with SetConsoleMode(), then
+// calls ReadConsoleInput() to get raw input which it remaps to Unix
+// terminal-style sequences which is returned via unix_read() which is used
+// by the 'adb shell' command.
+//
+// Code organization:
+//
+// * stdin_raw_init() and stdin_raw_restore() reconfigure the console.
+// * unix_read() detects console windows (as opposed to pipes, files, etc.).
+// * _console_read() is the main code of the emulation.
+
+
+// Read an input record from the console; one that should be processed.
+static bool _get_interesting_input_record_uncached(const HANDLE console,
+    INPUT_RECORD* const input_record) {
+    for (;;) {
+        DWORD read_count = 0;
+        memset(input_record, 0, sizeof(*input_record));
+        if (!ReadConsoleInputA(console, input_record, 1, &read_count)) {
+            D("_get_interesting_input_record_uncached: ReadConsoleInputA() "
+              "failure, error %ld\n", GetLastError());
+            errno = EIO;
+            return false;
+        }
+
+        if (read_count == 0) {   // should be impossible
+            fatal("ReadConsoleInputA returned 0");
+        }
+
+        if (read_count != 1) {   // should be impossible
+            fatal("ReadConsoleInputA did not return one input record");
+        }
+
+        if ((input_record->EventType == KEY_EVENT) &&
+            (input_record->Event.KeyEvent.bKeyDown)) {
+            if (input_record->Event.KeyEvent.wRepeatCount == 0) {
+                fatal("ReadConsoleInputA returned a key event with zero repeat"
+                      " count");
+            }
+
+            // Got an interesting INPUT_RECORD, so return
+            return true;
+        }
+    }
+}
+
+// Cached input record (in case _console_read() is passed a buffer that doesn't
+// have enough space to fit wRepeatCount number of key sequences). A non-zero
+// wRepeatCount indicates that a record is cached.
+static INPUT_RECORD _win32_input_record;
+
+// Get the next KEY_EVENT_RECORD that should be processed.
+static KEY_EVENT_RECORD* _get_key_event_record(const HANDLE console) {
+    // If nothing cached, read directly from the console until we get an
+    // interesting record.
+    if (_win32_input_record.Event.KeyEvent.wRepeatCount == 0) {
+        if (!_get_interesting_input_record_uncached(console,
+            &_win32_input_record)) {
+            // There was an error, so make sure wRepeatCount is zero because
+            // that signifies no cached input record.
+            _win32_input_record.Event.KeyEvent.wRepeatCount = 0;
+            return NULL;
+        }
+    }
+
+    return &_win32_input_record.Event.KeyEvent;
+}
+
+static __inline__ bool _is_shift_pressed(const DWORD control_key_state) {
+    return (control_key_state & SHIFT_PRESSED) != 0;
+}
+
+static __inline__ bool _is_ctrl_pressed(const DWORD control_key_state) {
+    return (control_key_state & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) != 0;
+}
+
+static __inline__ bool _is_alt_pressed(const DWORD control_key_state) {
+    return (control_key_state & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) != 0;
+}
+
+static __inline__ bool _is_numlock_on(const DWORD control_key_state) {
+    return (control_key_state & NUMLOCK_ON) != 0;
+}
+
+static __inline__ bool _is_capslock_on(const DWORD control_key_state) {
+    return (control_key_state & CAPSLOCK_ON) != 0;
+}
+
+static __inline__ bool _is_enhanced_key(const DWORD control_key_state) {
+    return (control_key_state & ENHANCED_KEY) != 0;
+}
+
+// Constants from MSDN for ToAscii().
+static const BYTE TOASCII_KEY_OFF = 0x00;
+static const BYTE TOASCII_KEY_DOWN = 0x80;
+static const BYTE TOASCII_KEY_TOGGLED_ON = 0x01;   // for CapsLock
+
+// Given a key event, ignore a modifier key and return the character that was
+// entered without the modifier. Writes to *ch and returns the number of bytes
+// written.
+static size_t _get_char_ignoring_modifier(char* const ch,
+    const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state,
+    const WORD modifier) {
+    // If there is no character from Windows, try ignoring the specified
+    // modifier and look for a character. Note that if AltGr is being used,
+    // there will be a character from Windows.
+    if (key_event->uChar.AsciiChar == '\0') {
+        // Note that we read the control key state from the passed in argument
+        // instead of from key_event since the argument has been normalized.
+        if (((modifier == VK_SHIFT)   &&
+            _is_shift_pressed(control_key_state)) ||
+            ((modifier == VK_CONTROL) &&
+            _is_ctrl_pressed(control_key_state)) ||
+            ((modifier == VK_MENU)    && _is_alt_pressed(control_key_state))) {
+
+            BYTE key_state[256]   = {0};
+            key_state[VK_SHIFT]   = _is_shift_pressed(control_key_state) ?
+                TOASCII_KEY_DOWN : TOASCII_KEY_OFF;
+            key_state[VK_CONTROL] = _is_ctrl_pressed(control_key_state)  ?
+                TOASCII_KEY_DOWN : TOASCII_KEY_OFF;
+            key_state[VK_MENU]    = _is_alt_pressed(control_key_state)   ?
+                TOASCII_KEY_DOWN : TOASCII_KEY_OFF;
+            key_state[VK_CAPITAL] = _is_capslock_on(control_key_state)   ?
+                TOASCII_KEY_TOGGLED_ON : TOASCII_KEY_OFF;
+
+            // cause this modifier to be ignored
+            key_state[modifier]   = TOASCII_KEY_OFF;
+
+            WORD translated = 0;
+            if (ToAscii(key_event->wVirtualKeyCode,
+                key_event->wVirtualScanCode, key_state, &translated, 0) == 1) {
+                // Ignoring the modifier, we found a character.
+                *ch = (CHAR)translated;
+                return 1;
+            }
+        }
+    }
+
+    // Just use whatever Windows told us originally.
+    *ch = key_event->uChar.AsciiChar;
+
+    // If the character from Windows is NULL, return a size of zero.
+    return (*ch == '\0') ? 0 : 1;
+}
+
+// If a Ctrl key is pressed, lookup the character, ignoring the Ctrl key,
+// but taking into account the shift key. This is because for a sequence like
+// Ctrl-Alt-0, we want to find the character '0' and for Ctrl-Alt-Shift-0,
+// we want to find the character ')'.
+//
+// Note that Windows doesn't seem to pass bKeyDown for Ctrl-Shift-NoAlt-0
+// because it is the default key-sequence to switch the input language.
+// This is configurable in the Region and Language control panel.
+static __inline__ size_t _get_non_control_char(char* const ch,
+    const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state) {
+    return _get_char_ignoring_modifier(ch, key_event, control_key_state,
+        VK_CONTROL);
+}
+
+// Get without Alt.
+static __inline__ size_t _get_non_alt_char(char* const ch,
+    const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state) {
+    return _get_char_ignoring_modifier(ch, key_event, control_key_state,
+        VK_MENU);
+}
+
+// Ignore the control key, find the character from Windows, and apply any
+// Control key mappings (for example, Ctrl-2 is a NULL character). Writes to
+// *pch and returns number of bytes written.
+static size_t _get_control_character(char* const pch,
+    const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state) {
+    const size_t len = _get_non_control_char(pch, key_event,
+        control_key_state);
+
+    if ((len == 1) && _is_ctrl_pressed(control_key_state)) {
+        char ch = *pch;
+        switch (ch) {
+        case '2':
+        case '@':
+        case '`':
+            ch = '\0';
+            break;
+        case '3':
+        case '[':
+        case '{':
+            ch = '\x1b';
+            break;
+        case '4':
+        case '\\':
+        case '|':
+            ch = '\x1c';
+            break;
+        case '5':
+        case ']':
+        case '}':
+            ch = '\x1d';
+            break;
+        case '6':
+        case '^':
+        case '~':
+            ch = '\x1e';
+            break;
+        case '7':
+        case '-':
+        case '_':
+            ch = '\x1f';
+            break;
+        case '8':
+            ch = '\x7f';
+            break;
+        case '/':
+            if (!_is_alt_pressed(control_key_state)) {
+                ch = '\x1f';
+            }
+            break;
+        case '?':
+            if (!_is_alt_pressed(control_key_state)) {
+                ch = '\x7f';
+            }
+            break;
+        }
+        *pch = ch;
+    }
+
+    return len;
+}
+
+static DWORD _normalize_altgr_control_key_state(
+    const KEY_EVENT_RECORD* const key_event) {
+    DWORD control_key_state = key_event->dwControlKeyState;
+
+    // If we're in an AltGr situation where the AltGr key is down (depending on
+    // the keyboard layout, that might be the physical right alt key which
+    // produces a control_key_state where Right-Alt and Left-Ctrl are down) or
+    // AltGr-equivalent keys are down (any Ctrl key + any Alt key), and we have
+    // a character (which indicates that there was an AltGr mapping), then act
+    // as if alt and control are not really down for the purposes of modifiers.
+    // This makes it so that if the user with, say, a German keyboard layout
+    // presses AltGr-] (which we see as Right-Alt + Left-Ctrl + key), we just
+    // output the key and we don't see the Alt and Ctrl keys.
+    if (_is_ctrl_pressed(control_key_state) &&
+        _is_alt_pressed(control_key_state)
+        && (key_event->uChar.AsciiChar != '\0')) {
+        // Try to remove as few bits as possible to improve our chances of
+        // detecting combinations like Left-Alt + AltGr, Right-Ctrl + AltGr, or
+        // Left-Alt + Right-Ctrl + AltGr.
+        if ((control_key_state & RIGHT_ALT_PRESSED) != 0) {
+            // Remove Right-Alt.
+            control_key_state &= ~RIGHT_ALT_PRESSED;
+            // If uChar is set, a Ctrl key is pressed, and Right-Alt is
+            // pressed, Left-Ctrl is almost always set, except if the user
+            // presses Right-Ctrl, then AltGr (in that specific order) for
+            // whatever reason. At any rate, make sure the bit is not set.
+            control_key_state &= ~LEFT_CTRL_PRESSED;
+        } else if ((control_key_state & LEFT_ALT_PRESSED) != 0) {
+            // Remove Left-Alt.
+            control_key_state &= ~LEFT_ALT_PRESSED;
+            // Whichever Ctrl key is down, remove it from the state. We only
+            // remove one key, to improve our chances of detecting the
+            // corner-case of Left-Ctrl + Left-Alt + Right-Ctrl.
+            if ((control_key_state & LEFT_CTRL_PRESSED) != 0) {
+                // Remove Left-Ctrl.
+                control_key_state &= ~LEFT_CTRL_PRESSED;
+            } else if ((control_key_state & RIGHT_CTRL_PRESSED) != 0) {
+                // Remove Right-Ctrl.
+                control_key_state &= ~RIGHT_CTRL_PRESSED;
+            }
+        }
+
+        // Note that this logic isn't 100% perfect because Windows doesn't
+        // allow us to detect all combinations because a physical AltGr key
+        // press shows up as two bits, plus some combinations are ambiguous
+        // about what is actually physically pressed.
+    }
+
+    return control_key_state;
+}
+
+// If NumLock is on and Shift is pressed, SHIFT_PRESSED is not set in
+// dwControlKeyState for the following keypad keys: period, 0-9. If we detect
+// this scenario, set the SHIFT_PRESSED bit so we can add modifiers
+// appropriately.
+static DWORD _normalize_keypad_control_key_state(const WORD vk,
+    const DWORD control_key_state) {
+    if (!_is_numlock_on(control_key_state)) {
+        return control_key_state;
+    }
+    if (!_is_enhanced_key(control_key_state)) {
+        switch (vk) {
+            case VK_INSERT: // 0
+            case VK_DELETE: // .
+            case VK_END:    // 1
+            case VK_DOWN:   // 2
+            case VK_NEXT:   // 3
+            case VK_LEFT:   // 4
+            case VK_CLEAR:  // 5
+            case VK_RIGHT:  // 6
+            case VK_HOME:   // 7
+            case VK_UP:     // 8
+            case VK_PRIOR:  // 9
+                return control_key_state | SHIFT_PRESSED;
+        }
+    }
+
+    return control_key_state;
+}
+
+static const char* _get_keypad_sequence(const DWORD control_key_state,
+    const char* const normal, const char* const shifted) {
+    if (_is_shift_pressed(control_key_state)) {
+        // Shift is pressed and NumLock is off
+        return shifted;
+    } else {
+        // Shift is not pressed and NumLock is off, or,
+        // Shift is pressed and NumLock is on, in which case we want the
+        // NumLock and Shift to neutralize each other, thus, we want the normal
+        // sequence.
+        return normal;
+    }
+    // If Shift is not pressed and NumLock is on, a different virtual key code
+    // is returned by Windows, which can be taken care of by a different case
+    // statement in _console_read().
+}
+
+// Write sequence to buf and return the number of bytes written.
+static size_t _get_modifier_sequence(char* const buf, const WORD vk,
+    DWORD control_key_state, const char* const normal) {
+    // Copy the base sequence into buf.
+    const size_t len = strlen(normal);
+    memcpy(buf, normal, len);
+
+    int code = 0;
+
+    control_key_state = _normalize_keypad_control_key_state(vk,
+        control_key_state);
+
+    if (_is_shift_pressed(control_key_state)) {
+        code |= 0x1;
+    }
+    if (_is_alt_pressed(control_key_state)) {   // any alt key pressed
+        code |= 0x2;
+    }
+    if (_is_ctrl_pressed(control_key_state)) {  // any control key pressed
+        code |= 0x4;
+    }
+    // If some modifier was held down, then we need to insert the modifier code
+    if (code != 0) {
+        if (len == 0) {
+            // Should be impossible because caller should pass a string of
+            // non-zero length.
+            return 0;
+        }
+        size_t index = len - 1;
+        const char lastChar = buf[index];
+        if (lastChar != '~') {
+            buf[index++] = '1';
+        }
+        buf[index++] = ';';         // modifier separator
+        // 2 = shift, 3 = alt, 4 = shift & alt, 5 = control,
+        // 6 = shift & control, 7 = alt & control, 8 = shift & alt & control
+        buf[index++] = '1' + code;
+        buf[index++] = lastChar;    // move ~ (or other last char) to the end
+        return index;
+    }
+    return len;
+}
+
+// Write sequence to buf and return the number of bytes written.
+static size_t _get_modifier_keypad_sequence(char* const buf, const WORD vk,
+    const DWORD control_key_state, const char* const normal,
+    const char shifted) {
+    if (_is_shift_pressed(control_key_state)) {
+        // Shift is pressed and NumLock is off
+        if (shifted != '\0') {
+            buf[0] = shifted;
+            return sizeof(buf[0]);
+        } else {
+            return 0;
+        }
+    } else {
+        // Shift is not pressed and NumLock is off, or,
+        // Shift is pressed and NumLock is on, in which case we want the
+        // NumLock and Shift to neutralize each other, thus, we want the normal
+        // sequence.
+        return _get_modifier_sequence(buf, vk, control_key_state, normal);
+    }
+    // If Shift is not pressed and NumLock is on, a different virtual key code
+    // is returned by Windows, which can be taken care of by a different case
+    // statement in _console_read().
+}
+
+// The decimal key on the keypad produces a '.' for U.S. English and a ',' for
+// Standard German. Figure this out at runtime so we know what to output for
+// Shift-VK_DELETE.
+static char _get_decimal_char() {
+    return (char)MapVirtualKeyA(VK_DECIMAL, MAPVK_VK_TO_CHAR);
+}
+
+// Prefix the len bytes in buf with the escape character, and then return the
+// new buffer length.
+size_t _escape_prefix(char* const buf, const size_t len) {
+    // If nothing to prefix, don't do anything. We might be called with
+    // len == 0, if alt was held down with a dead key which produced nothing.
+    if (len == 0) {
+        return 0;
+    }
+
+    memmove(&buf[1], buf, len);
+    buf[0] = '\x1b';
+    return len + 1;
+}
+
+// Writes to buffer buf (of length len), returning number of bytes written or
+// -1 on error. Never returns zero because Win32 consoles are never 'closed'
+// (as far as I can tell).
+static int _console_read(const HANDLE console, void* buf, size_t len) {
+    for (;;) {
+        KEY_EVENT_RECORD* const key_event = _get_key_event_record(console);
+        if (key_event == NULL) {
+            return -1;
+        }
+
+        const WORD vk = key_event->wVirtualKeyCode;
+        const CHAR ch = key_event->uChar.AsciiChar;
+        const DWORD control_key_state = _normalize_altgr_control_key_state(
+            key_event);
+
+        // The following emulation code should write the output sequence to
+        // either seqstr or to seqbuf and seqbuflen.
+        const char* seqstr = NULL;  // NULL terminated C-string
+        // Enough space for max sequence string below, plus modifiers and/or
+        // escape prefix.
+        char seqbuf[16];
+        size_t seqbuflen = 0;       // Space used in seqbuf.
+
+#define MATCH(vk, normal) \
+            case (vk): \
+            { \
+                seqstr = (normal); \
+            } \
+            break;
+
+        // Modifier keys should affect the output sequence.
+#define MATCH_MODIFIER(vk, normal) \
+            case (vk): \
+            { \
+                seqbuflen = _get_modifier_sequence(seqbuf, (vk), \
+                    control_key_state, (normal)); \
+            } \
+            break;
+
+        // The shift key should affect the output sequence.
+#define MATCH_KEYPAD(vk, normal, shifted) \
+            case (vk): \
+            { \
+                seqstr = _get_keypad_sequence(control_key_state, (normal), \
+                    (shifted)); \
+            } \
+            break;
+
+        // The shift key and other modifier keys should affect the output
+        // sequence.
+#define MATCH_MODIFIER_KEYPAD(vk, normal, shifted) \
+            case (vk): \
+            { \
+                seqbuflen = _get_modifier_keypad_sequence(seqbuf, (vk), \
+                    control_key_state, (normal), (shifted)); \
+            } \
+            break;
+
+#define ESC "\x1b"
+#define CSI ESC "["
+#define SS3 ESC "O"
+
+        // Only support normal mode, not application mode.
+
+        // Enhanced keys:
+        // * 6-pack: insert, delete, home, end, page up, page down
+        // * cursor keys: up, down, right, left
+        // * keypad: divide, enter
+        // * Undocumented: VK_PAUSE (Ctrl-NumLock), VK_SNAPSHOT,
+        //   VK_CANCEL (Ctrl-Pause/Break), VK_NUMLOCK
+        if (_is_enhanced_key(control_key_state)) {
+            switch (vk) {
+                case VK_RETURN: // Enter key on keypad
+                    if (_is_ctrl_pressed(control_key_state)) {
+                        seqstr = "\n";
+                    } else {
+                        seqstr = "\r";
+                    }
+                    break;
+
+                MATCH_MODIFIER(VK_PRIOR, CSI "5~"); // Page Up
+                MATCH_MODIFIER(VK_NEXT,  CSI "6~"); // Page Down
+
+                // gnome-terminal currently sends SS3 "F" and SS3 "H", but that
+                // will be fixed soon to match xterm which sends CSI "F" and
+                // CSI "H". https://bugzilla.redhat.com/show_bug.cgi?id=1119764
+                MATCH(VK_END,  CSI "F");
+                MATCH(VK_HOME, CSI "H");
+
+                MATCH_MODIFIER(VK_LEFT,  CSI "D");
+                MATCH_MODIFIER(VK_UP,    CSI "A");
+                MATCH_MODIFIER(VK_RIGHT, CSI "C");
+                MATCH_MODIFIER(VK_DOWN,  CSI "B");
+
+                MATCH_MODIFIER(VK_INSERT, CSI "2~");
+                MATCH_MODIFIER(VK_DELETE, CSI "3~");
+
+                MATCH(VK_DIVIDE, "/");
+            }
+        } else {    // Non-enhanced keys:
+            switch (vk) {
+                case VK_BACK:   // backspace
+                    if (_is_alt_pressed(control_key_state)) {
+                        seqstr = ESC "\x7f";
+                    } else {
+                        seqstr = "\x7f";
+                    }
+                    break;
+
+                case VK_TAB:
+                    if (_is_shift_pressed(control_key_state)) {
+                        seqstr = CSI "Z";
+                    } else {
+                        seqstr = "\t";
+                    }
+                    break;
+
+                // Number 5 key in keypad when NumLock is off, or if NumLock is
+                // on and Shift is down.
+                MATCH_KEYPAD(VK_CLEAR, CSI "E", "5");
+
+                case VK_RETURN:     // Enter key on main keyboard
+                    if (_is_alt_pressed(control_key_state)) {
+                        seqstr = ESC "\n";
+                    } else if (_is_ctrl_pressed(control_key_state)) {
+                        seqstr = "\n";
+                    } else {
+                        seqstr = "\r";
+                    }
+                    break;
+
+                // VK_ESCAPE: Don't do any special handling. The OS uses many
+                // of the sequences with Escape and many of the remaining
+                // sequences don't produce bKeyDown messages, only !bKeyDown
+                // for whatever reason.
+
+                case VK_SPACE:
+                    if (_is_alt_pressed(control_key_state)) {
+                        seqstr = ESC " ";
+                    } else if (_is_ctrl_pressed(control_key_state)) {
+                        seqbuf[0] = '\0';   // NULL char
+                        seqbuflen = 1;
+                    } else {
+                        seqstr = " ";
+                    }
+                    break;
+
+                MATCH_MODIFIER_KEYPAD(VK_PRIOR, CSI "5~", '9'); // Page Up
+                MATCH_MODIFIER_KEYPAD(VK_NEXT,  CSI "6~", '3'); // Page Down
+
+                MATCH_KEYPAD(VK_END,  CSI "4~", "1");
+                MATCH_KEYPAD(VK_HOME, CSI "1~", "7");
+
+                MATCH_MODIFIER_KEYPAD(VK_LEFT,  CSI "D", '4');
+                MATCH_MODIFIER_KEYPAD(VK_UP,    CSI "A", '8');
+                MATCH_MODIFIER_KEYPAD(VK_RIGHT, CSI "C", '6');
+                MATCH_MODIFIER_KEYPAD(VK_DOWN,  CSI "B", '2');
+
+                MATCH_MODIFIER_KEYPAD(VK_INSERT, CSI "2~", '0');
+                MATCH_MODIFIER_KEYPAD(VK_DELETE, CSI "3~",
+                    _get_decimal_char());
+
+                case 0x30:          // 0
+                case 0x31:          // 1
+                case 0x39:          // 9
+                case VK_OEM_1:      // ;:
+                case VK_OEM_PLUS:   // =+
+                case VK_OEM_COMMA:  // ,<
+                case VK_OEM_PERIOD: // .>
+                case VK_OEM_7:      // '"
+                case VK_OEM_102:    // depends on keyboard, could be <> or \|
+                case VK_OEM_2:      // /?
+                case VK_OEM_3:      // `~
+                case VK_OEM_4:      // [{
+                case VK_OEM_5:      // \|
+                case VK_OEM_6:      // ]}
+                {
+                    seqbuflen = _get_control_character(seqbuf, key_event,
+                        control_key_state);
+
+                    if (_is_alt_pressed(control_key_state)) {
+                        seqbuflen = _escape_prefix(seqbuf, seqbuflen);
+                    }
+                }
+                break;
+
+                case 0x32:          // 2
+                case 0x36:          // 6
+                case VK_OEM_MINUS:  // -_
+                {
+                    seqbuflen = _get_control_character(seqbuf, key_event,
+                        control_key_state);
+
+                    // If Alt is pressed and it isn't Ctrl-Alt-ShiftUp, then
+                    // prefix with escape.
+                    if (_is_alt_pressed(control_key_state) &&
+                        !(_is_ctrl_pressed(control_key_state) &&
+                        !_is_shift_pressed(control_key_state))) {
+                        seqbuflen = _escape_prefix(seqbuf, seqbuflen);
+                    }
+                }
+                break;
+
+                case 0x33:  // 3
+                case 0x34:  // 4
+                case 0x35:  // 5
+                case 0x37:  // 7
+                case 0x38:  // 8
+                {
+                    seqbuflen = _get_control_character(seqbuf, key_event,
+                        control_key_state);
+
+                    // If Alt is pressed and it isn't Ctrl-Alt-ShiftUp, then
+                    // prefix with escape.
+                    if (_is_alt_pressed(control_key_state) &&
+                        !(_is_ctrl_pressed(control_key_state) &&
+                        !_is_shift_pressed(control_key_state))) {
+                        seqbuflen = _escape_prefix(seqbuf, seqbuflen);
+                    }
+                }
+                break;
+
+                case 0x41:  // a
+                case 0x42:  // b
+                case 0x43:  // c
+                case 0x44:  // d
+                case 0x45:  // e
+                case 0x46:  // f
+                case 0x47:  // g
+                case 0x48:  // h
+                case 0x49:  // i
+                case 0x4a:  // j
+                case 0x4b:  // k
+                case 0x4c:  // l
+                case 0x4d:  // m
+                case 0x4e:  // n
+                case 0x4f:  // o
+                case 0x50:  // p
+                case 0x51:  // q
+                case 0x52:  // r
+                case 0x53:  // s
+                case 0x54:  // t
+                case 0x55:  // u
+                case 0x56:  // v
+                case 0x57:  // w
+                case 0x58:  // x
+                case 0x59:  // y
+                case 0x5a:  // z
+                {
+                    seqbuflen = _get_non_alt_char(seqbuf, key_event,
+                        control_key_state);
+
+                    // If Alt is pressed, then prefix with escape.
+                    if (_is_alt_pressed(control_key_state)) {
+                        seqbuflen = _escape_prefix(seqbuf, seqbuflen);
+                    }
+                }
+                break;
+
+                // These virtual key codes are generated by the keys on the
+                // keypad *when NumLock is on* and *Shift is up*.
+                MATCH(VK_NUMPAD0, "0");
+                MATCH(VK_NUMPAD1, "1");
+                MATCH(VK_NUMPAD2, "2");
+                MATCH(VK_NUMPAD3, "3");
+                MATCH(VK_NUMPAD4, "4");
+                MATCH(VK_NUMPAD5, "5");
+                MATCH(VK_NUMPAD6, "6");
+                MATCH(VK_NUMPAD7, "7");
+                MATCH(VK_NUMPAD8, "8");
+                MATCH(VK_NUMPAD9, "9");
+
+                MATCH(VK_MULTIPLY, "*");
+                MATCH(VK_ADD,      "+");
+                MATCH(VK_SUBTRACT, "-");
+                // VK_DECIMAL is generated by the . key on the keypad *when
+                // NumLock is on* and *Shift is up* and the sequence is not
+                // Ctrl-Alt-NoShift-. (which causes Ctrl-Alt-Del and the
+                // Windows Security screen to come up).
+                case VK_DECIMAL:
+                    // U.S. English uses '.', Germany German uses ','.
+                    seqbuflen = _get_non_control_char(seqbuf, key_event,
+                        control_key_state);
+                    break;
+
+                MATCH_MODIFIER(VK_F1,  SS3 "P");
+                MATCH_MODIFIER(VK_F2,  SS3 "Q");
+                MATCH_MODIFIER(VK_F3,  SS3 "R");
+                MATCH_MODIFIER(VK_F4,  SS3 "S");
+                MATCH_MODIFIER(VK_F5,  CSI "15~");
+                MATCH_MODIFIER(VK_F6,  CSI "17~");
+                MATCH_MODIFIER(VK_F7,  CSI "18~");
+                MATCH_MODIFIER(VK_F8,  CSI "19~");
+                MATCH_MODIFIER(VK_F9,  CSI "20~");
+                MATCH_MODIFIER(VK_F10, CSI "21~");
+                MATCH_MODIFIER(VK_F11, CSI "23~");
+                MATCH_MODIFIER(VK_F12, CSI "24~");
+
+                MATCH_MODIFIER(VK_F13, CSI "25~");
+                MATCH_MODIFIER(VK_F14, CSI "26~");
+                MATCH_MODIFIER(VK_F15, CSI "28~");
+                MATCH_MODIFIER(VK_F16, CSI "29~");
+                MATCH_MODIFIER(VK_F17, CSI "31~");
+                MATCH_MODIFIER(VK_F18, CSI "32~");
+                MATCH_MODIFIER(VK_F19, CSI "33~");
+                MATCH_MODIFIER(VK_F20, CSI "34~");
+
+                // MATCH_MODIFIER(VK_F21, ???);
+                // MATCH_MODIFIER(VK_F22, ???);
+                // MATCH_MODIFIER(VK_F23, ???);
+                // MATCH_MODIFIER(VK_F24, ???);
+            }
+        }
+
+#undef MATCH
+#undef MATCH_MODIFIER
+#undef MATCH_KEYPAD
+#undef MATCH_MODIFIER_KEYPAD
+#undef ESC
+#undef CSI
+#undef SS3
+
+        const char* out;
+        size_t outlen;
+
+        // Check for output in any of:
+        // * seqstr is set (and strlen can be used to determine the length).
+        // * seqbuf and seqbuflen are set
+        // Fallback to ch from Windows.
+        if (seqstr != NULL) {
+            out = seqstr;
+            outlen = strlen(seqstr);
+        } else if (seqbuflen > 0) {
+            out = seqbuf;
+            outlen = seqbuflen;
+        } else if (ch != '\0') {
+            // Use whatever Windows told us it is.
+            seqbuf[0] = ch;
+            seqbuflen = 1;
+            out = seqbuf;
+            outlen = seqbuflen;
+        } else {
+            // No special handling for the virtual key code and Windows isn't
+            // telling us a character code, then we don't know how to translate
+            // the key press.
+            //
+            // Consume the input and 'continue' to cause us to get a new key
+            // event.
+            D("_console_read: unknown virtual key code: %d, enhanced: %s\n",
+                vk, _is_enhanced_key(control_key_state) ? "true" : "false");
+            key_event->wRepeatCount = 0;
+            continue;
+        }
+
+        int bytesRead = 0;
+
+        // put output wRepeatCount times into buf/len
+        while (key_event->wRepeatCount > 0) {
+            if (len >= outlen) {
+                // Write to buf/len
+                memcpy(buf, out, outlen);
+                buf = (void*)((char*)buf + outlen);
+                len -= outlen;
+                bytesRead += outlen;
+
+                // consume the input
+                --key_event->wRepeatCount;
+            } else {
+                // Not enough space, so just leave it in _win32_input_record
+                // for a subsequent retrieval.
+                if (bytesRead == 0) {
+                    // We didn't write anything because there wasn't enough
+                    // space to even write one sequence. This should never
+                    // happen if the caller uses sensible buffer sizes
+                    // (i.e. >= maximum sequence length which is probably a
+                    // few bytes long).
+                    D("_console_read: no buffer space to write one sequence; "
+                        "buffer: %ld, sequence: %ld\n", (long)len,
+                        (long)outlen);
+                    errno = ENOMEM;
+                    return -1;
+                } else {
+                    // Stop trying to write to buf/len, just return whatever
+                    // we wrote so far.
+                    break;
+                }
+            }
+        }
+
+        return bytesRead;
+    }
+}
+
+static DWORD _old_console_mode; // previous GetConsoleMode() result
+static HANDLE _console_handle;  // when set, console mode should be restored
+
+void stdin_raw_init(const int fd) {
+    if (STDIN_FILENO == fd) {
+        const HANDLE in = GetStdHandle(STD_INPUT_HANDLE);
+        if ((in == INVALID_HANDLE_VALUE) || (in == NULL)) {
+            return;
+        }
+
+        if (GetFileType(in) != FILE_TYPE_CHAR) {
+            // stdin might be a file or pipe.
+            return;
+        }
+
+        if (!GetConsoleMode(in, &_old_console_mode)) {
+            // If GetConsoleMode() fails, stdin is probably is not a console.
+            return;
+        }
+
+        // Disable ENABLE_PROCESSED_INPUT so that Ctrl-C is read instead of
+        // calling the process Ctrl-C routine (configured by
+        // SetConsoleCtrlHandler()).
+        // Disable ENABLE_LINE_INPUT so that input is immediately sent.
+        // Disable ENABLE_ECHO_INPUT to disable local echo. Disabling this
+        // flag also seems necessary to have proper line-ending processing.
+        if (!SetConsoleMode(in, _old_console_mode & ~(ENABLE_PROCESSED_INPUT |
+            ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT))) {
+            // This really should not fail.
+            D("stdin_raw_init: SetConsoleMode() failure, error %ld\n",
+                GetLastError());
+        }
+
+        // Once this is set, it means that stdin has been configured for
+        // reading from and that the old console mode should be restored later.
+        _console_handle = in;
+
+        // Note that we don't need to configure C Runtime line-ending
+        // translation because _console_read() does not call the C Runtime to
+        // read from the console.
+    }
+}
+
+void stdin_raw_restore(const int fd) {
+    if (STDIN_FILENO == fd) {
+        if (_console_handle != NULL) {
+            const HANDLE in = _console_handle;
+            _console_handle = NULL;  // clear state
+
+            if (!SetConsoleMode(in, _old_console_mode)) {
+                // This really should not fail.
+                D("stdin_raw_restore: SetConsoleMode() failure, error %ld\n",
+                    GetLastError());
+            }
+        }
+    }
+}
+
+// Called by 'adb shell' command to read from stdin.
+int unix_read(int fd, void* buf, size_t len) {
+    if ((fd == STDIN_FILENO) && (_console_handle != NULL)) {
+        // If it is a request to read from stdin, and stdin_raw_init() has been
+        // called, and it successfully configured the console, then read from
+        // the console using Win32 console APIs and partially emulate a unix
+        // terminal.
+        return _console_read(_console_handle, buf, len);
+    } else {
+        // Just call into C Runtime which can read from pipes/files and which
+        // can do LF/CR translation.
+#undef read
+        return read(fd, buf, len);
+    }
+}
diff --git a/base/Android.mk b/base/Android.mk
index 7bd317b..ad85c6b 100644
--- a/base/Android.mk
+++ b/base/Android.mk
@@ -18,13 +18,11 @@
 
 libbase_src_files := \
     file.cpp \
-    logging.cpp \
     stringprintf.cpp \
     strings.cpp \
 
 libbase_test_src_files := \
     file_test.cpp \
-    logging_test.cpp \
     stringprintf_test.cpp \
     strings_test.cpp \
     test_main.cpp \
@@ -40,7 +38,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := libbase
 LOCAL_CLANG := true
-LOCAL_SRC_FILES := $(libbase_src_files)
+LOCAL_SRC_FILES := $(libbase_src_files) logging.cpp
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 LOCAL_CPPFLAGS := $(libbase_cppflags)
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
@@ -63,6 +61,9 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := libbase
 LOCAL_SRC_FILES := $(libbase_src_files)
+ifneq ($(HOST_OS),windows)
+    LOCAL_SRC_FILES += logging.cpp
+endif
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 LOCAL_CPPFLAGS := $(libbase_cppflags)
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
@@ -84,7 +85,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := libbase_test
 LOCAL_CLANG := true
-LOCAL_SRC_FILES := $(libbase_test_src_files)
+LOCAL_SRC_FILES := $(libbase_test_src_files) logging_test.cpp
 LOCAL_C_INCLUDES := $(LOCAL_PATH)
 LOCAL_CPPFLAGS := $(libbase_cppflags)
 LOCAL_SHARED_LIBRARIES := libbase
@@ -96,6 +97,9 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := libbase_test
 LOCAL_SRC_FILES := $(libbase_test_src_files)
+ifneq ($(HOST_OS),windows)
+    LOCAL_SRC_FILES += logging_test.cpp
+endif
 LOCAL_C_INCLUDES := $(LOCAL_PATH)
 LOCAL_CPPFLAGS := $(libbase_cppflags)
 LOCAL_SHARED_LIBRARIES := libbase
diff --git a/base/file.cpp b/base/file.cpp
index 118071e..a51c5ff 100644
--- a/base/file.cpp
+++ b/base/file.cpp
@@ -26,6 +26,7 @@
 #include "base/macros.h"  // For TEMP_FAILURE_RETRY on Darwin.
 #define LOG_TAG "base.file"
 #include "cutils/log.h"
+#include "utils/Compat.h"
 
 namespace android {
 namespace base {
diff --git a/base/logging.cpp b/base/logging.cpp
index 8bfb204..38ee2af 100644
--- a/base/logging.cpp
+++ b/base/logging.cpp
@@ -18,6 +18,7 @@
 
 #include <iostream>
 #include <limits>
+#include <mutex>
 #include <sstream>
 #include <string>
 #include <vector>
diff --git a/base/strings.cpp b/base/strings.cpp
index 5f7eccc..6f698d9 100644
--- a/base/strings.cpp
+++ b/base/strings.cpp
@@ -17,6 +17,7 @@
 #include "base/strings.h"
 
 #include <stdlib.h>
+#include <string.h>
 
 #include <string>
 #include <vector>
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index 64f7edc..97cf811 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -24,6 +24,7 @@
 
 struct fs_mgr_flag_values {
     char *key_loc;
+    char *verity_loc;
     long long part_length;
     char *label;
     int partnum;
@@ -108,6 +109,14 @@
                      * location of the keys.  Get it and return it.
                      */
                     flag_vals->key_loc = strdup(strchr(p, '=') + 1);
+                } else if ((fl[i].flag == MF_VERIFY) && flag_vals) {
+                    /* If the verify flag is followed by an = and the
+                     * location for the verity state,  get it and return it.
+                     */
+                    char *start = strchr(p, '=');
+                    if (start) {
+                        flag_vals->verity_loc = strdup(start + 1);
+                    }
                 } else if ((fl[i].flag == MF_FORCECRYPT) && flag_vals) {
                     /* The forceencrypt flag is followed by an = and the
                      * location of the keys.  Get it and return it.
@@ -292,6 +301,7 @@
         fstab->recs[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags,
                                                     &flag_vals, NULL, 0);
         fstab->recs[cnt].key_loc = flag_vals.key_loc;
+        fstab->recs[cnt].verity_loc = flag_vals.verity_loc;
         fstab->recs[cnt].length = flag_vals.part_length;
         fstab->recs[cnt].label = flag_vals.label;
         fstab->recs[cnt].partnum = flag_vals.partnum;
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index 5c67333..acdc5a3 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -47,16 +47,23 @@
 #define VERITY_METADATA_SIZE 32768
 #define VERITY_TABLE_RSA_KEY "/verity_key"
 
+#define METADATA_MAGIC 0x01564c54
+#define METADATA_TAG_MAX_LENGTH 63
+#define METADATA_EOD "eod"
+
+#define VERITY_STATE_TAG "verity_state"
 #define VERITY_STATE_HEADER 0x83c0ae9d
 #define VERITY_STATE_VERSION 1
 
 #define VERITY_KMSG_RESTART "dm-verity device corrupted"
 #define VERITY_KMSG_BUFSIZE 1024
 
+#define __STRINGIFY(x) #x
+#define STRINGIFY(x) __STRINGIFY(x)
+
 struct verity_state {
     uint32_t header;
     uint32_t version;
-    uint32_t size;
     int32_t mode;
 };
 
@@ -453,17 +460,116 @@
     return 0;
 }
 
+static int metadata_add(FILE *fp, long start, const char *tag,
+        unsigned int length, off64_t *offset)
+{
+    if (fseek(fp, start, SEEK_SET) < 0 ||
+        fprintf(fp, "%s %u\n", tag, length) < 0) {
+        return -1;
+    }
+
+    *offset = ftell(fp);
+
+    if (fseek(fp, length, SEEK_CUR) < 0 ||
+        fprintf(fp, METADATA_EOD " 0\n") < 0) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static int metadata_find(const char *fname, const char *stag,
+        unsigned int slength, off64_t *offset)
+{
+    FILE *fp = NULL;
+    char tag[METADATA_TAG_MAX_LENGTH + 1];
+    int rc = -1;
+    int n;
+    long start = 0x4000; /* skip cryptfs metadata area */
+    uint32_t magic;
+    unsigned int length = 0;
+
+    if (!fname) {
+        return -1;
+    }
+
+    fp = fopen(fname, "r+");
+
+    if (!fp) {
+        ERROR("Failed to open %s (%s)\n", fname, strerror(errno));
+        goto out;
+    }
+
+    /* check magic */
+    if (fseek(fp, start, SEEK_SET) < 0 ||
+        fread(&magic, sizeof(magic), 1, fp) != 1) {
+        ERROR("Failed to read magic from %s (%s)\n", fname, strerror(errno));
+        goto out;
+    }
+
+    if (magic != METADATA_MAGIC) {
+        magic = METADATA_MAGIC;
+
+        if (fseek(fp, start, SEEK_SET) < 0 ||
+            fwrite(&magic, sizeof(magic), 1, fp) != 1) {
+            ERROR("Failed to write magic to %s (%s)\n", fname, strerror(errno));
+            goto out;
+        }
+
+        rc = metadata_add(fp, start + sizeof(magic), stag, slength, offset);
+        if (rc < 0) {
+            ERROR("Failed to add metadata to %s: %s\n", fname, strerror(errno));
+        }
+
+        goto out;
+    }
+
+    start += sizeof(magic);
+
+    while (1) {
+        n = fscanf(fp, "%" STRINGIFY(METADATA_TAG_MAX_LENGTH) "s %u\n",
+                tag, &length);
+
+        if (n == 2 && strcmp(tag, METADATA_EOD)) {
+            /* found a tag */
+            start = ftell(fp);
+
+            if (!strcmp(tag, stag) && length == slength) {
+                *offset = start;
+                rc = 0;
+                goto out;
+            }
+
+            start += length;
+
+            if (fseek(fp, length, SEEK_CUR) < 0) {
+                ERROR("Failed to seek %s (%s)\n", fname, strerror(errno));
+                goto out;
+            }
+        } else {
+            rc = metadata_add(fp, start, stag, slength, offset);
+            if (rc < 0) {
+                ERROR("Failed to write metadata to %s: %s\n", fname,
+                    strerror(errno));
+            }
+            goto out;
+        }
+   }
+
+out:
+    if (fp) {
+        fflush(fp);
+        fclose(fp);
+    }
+
+    return rc;
+}
+
 static int write_verity_state(const char *fname, off64_t offset, int32_t mode)
 {
     int fd;
     int rc = -1;
-
-    struct verity_state s = {
-        VERITY_STATE_HEADER,
-        VERITY_STATE_VERSION,
-        sizeof(struct verity_state),
-        mode
-    };
+    struct verity_state s = { VERITY_STATE_HEADER, VERITY_STATE_VERSION, mode };
 
     fd = TEMP_FAILURE_RETRY(open(fname, O_WRONLY | O_SYNC | O_CLOEXEC));
 
@@ -472,13 +578,9 @@
         goto out;
     }
 
-    if (TEMP_FAILURE_RETRY(lseek64(fd, offset, SEEK_SET)) < 0) {
-        ERROR("Failed to seek %s to %" PRIu64 " (%s)\n", fname, offset, strerror(errno));
-        goto out;
-    }
-
-    if (TEMP_FAILURE_RETRY(write(fd, &s, sizeof(s))) != sizeof(s)) {
-        ERROR("Failed to write %zu bytes to %s (%s)\n", sizeof(s), fname, strerror(errno));
+    if (TEMP_FAILURE_RETRY(pwrite64(fd, &s, sizeof(s), offset)) != sizeof(s)) {
+        ERROR("Failed to write %zu bytes to %s to offset %" PRIu64 " (%s)\n",
+            sizeof(s), fname, offset, strerror(errno));
         goto out;
     }
 
@@ -492,44 +594,16 @@
     return rc;
 }
 
-static int get_verity_state_location(char *location, off64_t *offset)
+static int load_verity_state(struct fstab_rec *fstab, int *mode)
 {
-    char state_off[PROPERTY_VALUE_MAX];
-
-    if (property_get("ro.verity.state.location", location, NULL) <= 0) {
-        return -1;
-    }
-
-    if (*location != '/' || access(location, R_OK | W_OK) == -1) {
-        ERROR("Failed to access verity state %s (%s)\n", location, strerror(errno));
-        return -1;
-    }
-
-    *offset = 0;
-
-    if (property_get("ro.verity.state.offset", state_off, NULL) > 0) {
-        *offset = strtoll(state_off, NULL, 0);
-
-        if (errno == ERANGE || errno == EINVAL) {
-            ERROR("Invalid value in ro.verity.state.offset (%s)\n", state_off);
-            return -1;
-        }
-    }
-
-    return 0;
-}
-
-int fs_mgr_load_verity_state(int *mode)
-{
-    char fname[PROPERTY_VALUE_MAX];
     int fd = -1;
     int rc = -1;
     off64_t offset = 0;
     struct verity_state s;
 
-    if (get_verity_state_location(fname, &offset) < 0) {
-        /* location for dm-verity state is not specified, fall back to
-         * default behavior: return -EIO for corrupted blocks */
+    if (metadata_find(fstab->verity_loc, VERITY_STATE_TAG, sizeof(s),
+            &offset) < 0) {
+        /* fall back to stateless behavior */
         *mode = VERITY_MODE_EIO;
         rc = 0;
         goto out;
@@ -539,28 +613,27 @@
         /* device was restarted after dm-verity detected a corrupted
          * block, so switch to logging mode */
         *mode = VERITY_MODE_LOGGING;
-        rc = write_verity_state(fname, offset, *mode);
+        rc = write_verity_state(fstab->verity_loc, offset, *mode);
         goto out;
     }
 
-    fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC));
+    fd = TEMP_FAILURE_RETRY(open(fstab->verity_loc, O_RDONLY | O_CLOEXEC));
 
     if (fd == -1) {
-        ERROR("Failed to open %s (%s)\n", fname, strerror(errno));
+        ERROR("Failed to open %s (%s)\n", fstab->verity_loc, strerror(errno));
         goto out;
     }
 
-    if (TEMP_FAILURE_RETRY(lseek64(fd, offset, SEEK_SET)) < 0) {
-        ERROR("Failed to seek %s to %" PRIu64 " (%s)\n", fname, offset, strerror(errno));
-        goto out;
-    }
-
-    if (TEMP_FAILURE_RETRY(read(fd, &s, sizeof(s))) != sizeof(s)) {
-        ERROR("Failed to read %zu bytes from %s (%s)\n", sizeof(s), fname, strerror(errno));
+    if (TEMP_FAILURE_RETRY(pread64(fd, &s, sizeof(s), offset)) != sizeof(s)) {
+        ERROR("Failed to read %zu bytes from %s offset %" PRIu64 " (%s)\n",
+            sizeof(s), fstab->verity_loc, offset, strerror(errno));
         goto out;
     }
 
     if (s.header != VERITY_STATE_HEADER) {
+        /* space allocated, but no state written. write default state */
+        *mode = VERITY_MODE_DEFAULT;
+        rc = write_verity_state(fstab->verity_loc, offset, *mode);
         goto out;
     }
 
@@ -569,11 +642,6 @@
         goto out;
     }
 
-    if (s.size != sizeof(s)) {
-        ERROR("Unexpected verity state size (%u)\n", s.size);
-        goto out;
-    }
-
     if (s.mode < VERITY_MODE_EIO ||
         s.mode > VERITY_MODE_LAST) {
         ERROR("Unsupported verity mode (%u)\n", s.mode);
@@ -591,13 +659,61 @@
     return rc;
 }
 
+int fs_mgr_load_verity_state(int *mode)
+{
+    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
+    char propbuf[PROPERTY_VALUE_MAX];
+    int rc = -1;
+    int i;
+    struct fstab *fstab = NULL;
+
+    *mode = VERITY_MODE_DEFAULT;
+
+    property_get("ro.hardware", propbuf, "");
+    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
+
+    fstab = fs_mgr_read_fstab(fstab_filename);
+
+    if (!fstab) {
+        ERROR("Failed to read %s\n", fstab_filename);
+        goto out;
+    }
+
+    for (i = 0; i < fstab->num_entries; i++) {
+        if (!fs_mgr_is_verified(&fstab->recs[i])) {
+            continue;
+        }
+
+        rc = load_verity_state(&fstab->recs[i], mode);
+        if (rc < 0) {
+            continue;
+        }
+
+        /* if any of the verified partitions are in logging mode, return */
+        if (*mode == VERITY_MODE_LOGGING) {
+            rc = 0;
+            goto out;
+        }
+    }
+
+    /* if there were multiple partitions, all in non-logging mode, return the
+     * state of the last one */
+    rc = 0;
+
+out:
+    if (fstab) {
+        fs_mgr_free_fstab(fstab);
+    }
+
+    return rc;
+}
+
 int fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback)
 {
     _Alignas(struct dm_ioctl) char buffer[DM_BUF_SIZE];
     char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
     char *mount_point;
     char propbuf[PROPERTY_VALUE_MAX];
-    char state_loc[PROPERTY_VALUE_MAX];
     char *status;
     int fd = -1;
     int i;
@@ -606,10 +722,6 @@
     struct dm_ioctl *io = (struct dm_ioctl *) buffer;
     struct fstab *fstab = NULL;
 
-    if (get_verity_state_location(state_loc, &offset) < 0) {
-        goto out;
-    }
-
     fd = TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC));
 
     if (fd == -1) {
@@ -632,6 +744,11 @@
             continue;
         }
 
+        if (metadata_find(fstab->recs[i].verity_loc, VERITY_STATE_TAG,
+                sizeof(struct verity_state), &offset) < 0) {
+            continue;
+        }
+
         mount_point = basename(fstab->recs[i].mount_point);
         verity_ioctl_init(io, mount_point, 0);
 
@@ -644,7 +761,8 @@
         status = &buffer[io->data_start + sizeof(struct dm_target_spec)];
 
         if (*status == 'C') {
-            rc = write_verity_state(state_loc, offset, VERITY_MODE_LOGGING);
+            rc = write_verity_state(fstab->recs[i].verity_loc, offset,
+                    VERITY_MODE_LOGGING);
 
             if (rc == -1) {
                 goto out;
@@ -732,8 +850,12 @@
         goto out;
     }
 
-    if (fs_mgr_load_verity_state(&mode) < 0) {
-        mode = VERITY_MODE_RESTART; /* default dm-verity mode */
+    if (load_verity_state(fstab, &mode) < 0) {
+        /* if accessing or updating the state failed, switch to the default
+         * safe mode. This makes sure the device won't end up in an endless
+         * restart loop, and no corrupted data will be exposed to userspace
+         * without a warning. */
+        mode = VERITY_MODE_EIO;
     }
 
     INFO("Enabling dm-verity for %s (mode %d)\n",  mount_point, mode);
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 1af16c2..2655100 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -36,7 +36,8 @@
     VERITY_MODE_EIO = 0,
     VERITY_MODE_LOGGING = 1,
     VERITY_MODE_RESTART = 2,
-    VERITY_MODE_LAST = VERITY_MODE_RESTART
+    VERITY_MODE_LAST = VERITY_MODE_RESTART,
+    VERITY_MODE_DEFAULT = VERITY_MODE_RESTART
 };
 
 /*
diff --git a/include/cutils/klog.h b/include/cutils/klog.h
index d5ae6d7..295d62b 100644
--- a/include/cutils/klog.h
+++ b/include/cutils/klog.h
@@ -18,6 +18,7 @@
 #define _CUTILS_KLOG_H_
 
 #include <sys/cdefs.h>
+#include <sys/uio.h>
 #include <stdarg.h>
 
 __BEGIN_DECLS
@@ -26,9 +27,10 @@
 int  klog_get_level(void);
 void klog_set_level(int level);
 /* TODO: void klog_close(void); - and make klog_fd users thread safe. */
+
 void klog_write(int level, const char *fmt, ...)
     __attribute__ ((format(printf, 2, 3)));
-void klog_vwrite(int level, const char *fmt, va_list ap);
+void klog_writev(int level, const struct iovec* iov, int iov_count);
 
 __END_DECLS
 
diff --git a/include/system/graphics.h b/include/system/graphics.h
index c9f5950..c0f03fa 100644
--- a/include/system/graphics.h
+++ b/include/system/graphics.h
@@ -244,6 +244,56 @@
     HAL_PIXEL_FORMAT_RAW10 = 0x25,
 
     /*
+     * Android RAW12 format:
+     *
+     * This format is exposed outside of camera HAL to applications.
+     *
+     * RAW12 is a single-channel, 12-bit per pixel, densely packed in each row,
+     * unprocessed format, usually representing raw Bayer-pattern images coming from
+     * an image sensor.
+     *
+     * In an image buffer with this format, starting from the first pixel of each
+     * row, each two consecutive pixels are packed into 3 bytes (24 bits). The first
+     * and second byte contains the top 8 bits of first and second pixel. The third
+     * byte contains the 4 least significant bits of the two pixels, the exact layout
+     * data for each two consecutive pixels is illustrated below (Pi[j] stands for
+     * the jth bit of the ith pixel):
+     *
+     *           bit 7                                            bit 0
+     *          ======|======|======|======|======|======|======|======|
+     * Byte 0: |P0[11]|P0[10]|P0[ 9]|P0[ 8]|P0[ 7]|P0[ 6]|P0[ 5]|P0[ 4]|
+     *         |------|------|------|------|------|------|------|------|
+     * Byte 1: |P1[11]|P1[10]|P1[ 9]|P1[ 8]|P1[ 7]|P1[ 6]|P1[ 5]|P1[ 4]|
+     *         |------|------|------|------|------|------|------|------|
+     * Byte 2: |P1[ 3]|P1[ 2]|P1[ 1]|P1[ 0]|P0[ 3]|P0[ 2]|P0[ 1]|P0[ 0]|
+     *          =======================================================
+     *
+     * This format assumes:
+     * - a width multiple of 4 pixels
+     * - an even height
+     * - a vertical stride equal to the height
+     * - strides are specified in bytes, not in pixels
+     *
+     *   size = stride * height
+     *
+     * When stride is equal to width * (12 / 8), there will be no padding bytes at
+     * the end of each row, the entire image data is densely packed. When stride is
+     * larger than width * (12 / 8), padding bytes will be present at the end of
+     * each row (including the last row).
+     *
+     * This format must be accepted by the gralloc module when used with the
+     * following usage flags:
+     *    - GRALLOC_USAGE_HW_CAMERA_*
+     *    - GRALLOC_USAGE_SW_*
+     *    - GRALLOC_USAGE_RENDERSCRIPT
+     *
+     * When used with ANativeWindow, the dataSpace field should be
+     * HAL_DATASPACE_ARBITRARY, as raw image sensor buffers require substantial
+     * extra metadata to define.
+     */
+    HAL_PIXEL_FORMAT_RAW12 = 0x26,
+
+    /*
      * Android opaque RAW format:
      *
      * This format is exposed outside of the camera HAL to applications.
diff --git a/include/utils/Compat.h b/include/utils/Compat.h
index a238afe..ca4a8e0 100644
--- a/include/utils/Compat.h
+++ b/include/utils/Compat.h
@@ -36,7 +36,7 @@
 #endif /* __APPLE__ */
 
 #if defined(_WIN32)
-#define O_CLOEXEC 0
+#define O_CLOEXEC O_NOINHERIT
 #define O_NOFOLLOW 0
 #define DEFFILEMODE 0666
 #endif /* _WIN32 */
diff --git a/include/utils/Looper.h b/include/utils/Looper.h
index a381251..da2d5f2 100644
--- a/include/utils/Looper.h
+++ b/include/utils/Looper.h
@@ -447,8 +447,7 @@
 
     const bool mAllowNonCallbacks; // immutable
 
-    int mWakeReadPipeFd;  // immutable
-    int mWakeWritePipeFd; // immutable
+    int mWakeEventFd;  // immutable
     Mutex mLock;
 
     Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock
diff --git a/init/Android.mk b/init/Android.mk
index 5b8094f..94d3dad 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -18,17 +18,21 @@
     -Wno-unused-parameter \
     -Werror \
 
+init_clang := true
+
 # --
 
 include $(CLEAR_VARS)
 LOCAL_CPPFLAGS := $(init_cflags)
 LOCAL_SRC_FILES:= \
     init_parser.cpp \
+    log.cpp \
     parser.cpp \
     util.cpp \
 
 LOCAL_STATIC_LIBRARIES := libbase
 LOCAL_MODULE := libinit
+LOCAL_CLANG := $(init_clang)
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -68,6 +72,7 @@
     ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \
     ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdogd
 
+LOCAL_CLANG := $(init_clang)
 include $(BUILD_EXECUTABLE)
 
 
@@ -84,4 +89,5 @@
     libbase \
 
 LOCAL_STATIC_LIBRARIES := libinit
+LOCAL_CLANG := $(init_clang)
 include $(BUILD_NATIVE_TEST)
diff --git a/init/bootchart.cpp b/init/bootchart.cpp
index 03c8b30..95687cb 100644
--- a/init/bootchart.cpp
+++ b/init/bootchart.cpp
@@ -195,13 +195,8 @@
     }
 
     // Create kernel process accounting file.
-    {
-        int  fd = open( LOG_ACCT, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC,0644);
-        if (fd >= 0) {
-            close(fd);
-            acct( LOG_ACCT );
-        }
-    }
+    close(open(LOG_ACCT, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644));
+    acct(LOG_ACCT);
 
     log_header();
     return count;
@@ -210,11 +205,12 @@
 int do_bootchart_init(int nargs, char** args) {
     g_remaining_samples = bootchart_init();
     if (g_remaining_samples < 0) {
-        ERROR("bootcharting init failure: %s\n", strerror(errno));
+        ERROR("Bootcharting init failure: %s\n", strerror(errno));
     } else if (g_remaining_samples > 0) {
-        NOTICE("bootcharting started (will run for %d ms)\n", g_remaining_samples*BOOTCHART_POLLING_MS);
+        NOTICE("Bootcharting started (will run for %d s).\n",
+               (g_remaining_samples * BOOTCHART_POLLING_MS) / 1000);
     } else {
-        NOTICE("bootcharting ignored\n");
+        NOTICE("Not bootcharting.\n");
     }
     return 0;
 }
diff --git a/init/devices.cpp b/init/devices.cpp
index 9bce39a..96b1696 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -364,13 +364,6 @@
     return 0;
 }
 
-static inline suseconds_t get_usecs(void)
-{
-    struct timeval tv;
-    gettimeofday(&tv, 0);
-    return tv.tv_sec * (suseconds_t) 1000000 + tv.tv_usec;
-}
-
 static void parse_event(const char *msg, struct uevent *uevent)
 {
     uevent->action = "";
@@ -990,12 +983,7 @@
     }
 }
 
-void device_init(void)
-{
-    suseconds_t t0, t1;
-    struct stat info;
-    int fd;
-
+void device_init() {
     sehandle = NULL;
     if (is_selinux_enabled() > 0) {
         sehandle = selinux_android_file_context_handle();
@@ -1004,26 +992,22 @@
 
     /* is 256K enough? udev uses 16MB! */
     device_fd = uevent_open_socket(256*1024, true);
-    if(device_fd < 0)
+    if (device_fd == -1) {
         return;
-
-    fcntl(device_fd, F_SETFD, FD_CLOEXEC);
+    }
     fcntl(device_fd, F_SETFL, O_NONBLOCK);
 
-    if (stat(COLDBOOT_DONE, &info) < 0) {
-        t0 = get_usecs();
-        coldboot("/sys/class");
-        coldboot("/sys/block");
-        coldboot("/sys/devices");
-        t1 = get_usecs();
-        fd = open(COLDBOOT_DONE, O_WRONLY|O_CREAT|O_CLOEXEC, 0000);
-        close(fd);
-        if (LOG_UEVENTS) {
-            INFO("coldboot %ld uS\n", ((long) (t1 - t0)));
-        }
-    } else if (LOG_UEVENTS) {
-        INFO("skipping coldboot, already done\n");
+    if (access(COLDBOOT_DONE, F_OK) == 0) {
+        NOTICE("Skipping coldboot, already done!\n");
+        return;
     }
+
+    Timer t;
+    coldboot("/sys/class");
+    coldboot("/sys/block");
+    coldboot("/sys/devices");
+    close(open(COLDBOOT_DONE, O_WRONLY|O_CREAT|O_CLOEXEC, 0000));
+    NOTICE("Coldboot took %.2fs.\n", t.duration());
 }
 
 int get_device_fd()
diff --git a/init/init.cpp b/init/init.cpp
index 1449bc6..b1d65db 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -83,7 +83,7 @@
 bool waiting_for_exec = false;
 
 void service::NotifyStateChange(const char* new_state) {
-    if (!properties_inited()) {
+    if (!properties_initialized()) {
         // If properties aren't available yet, we can't set them.
         return;
     }
@@ -246,7 +246,7 @@
         }
     }
 
-    NOTICE("starting '%s'\n", svc->name);
+    NOTICE("Starting service '%s'...\n", svc->name);
 
     pid_t pid = fork();
     if (pid == 0) {
@@ -256,7 +256,7 @@
         int fd, sz;
 
         umask(077);
-        if (properties_inited()) {
+        if (properties_initialized()) {
             get_property_workspace(&fd, &sz);
             snprintf(tmp, sizeof(tmp), "%d,%d", dup(fd), sz);
             add_environment("ANDROID_PROPERTY_WORKSPACE", tmp);
@@ -397,7 +397,7 @@
     }
 
     if (svc->pid) {
-        NOTICE("service '%s' is being killed\n", svc->name);
+        NOTICE("Service '%s' is being killed...\n", svc->name);
         kill(-svc->pid, SIGKILL);
         svc->NotifyStateChange("stopping");
     } else {
@@ -559,17 +559,18 @@
     }
 }
 
-void execute_one_command(void)
-{
-    int ret, i;
+void execute_one_command() {
+    Timer t;
+
     char cmd_str[256] = "";
     char name_str[256] = "";
 
     if (!cur_action || !cur_command || is_last_command(cur_action, cur_command)) {
         cur_action = action_remove_queue_head();
         cur_command = NULL;
-        if (!cur_action)
+        if (!cur_action) {
             return;
+        }
 
         build_triggers_string(name_str, sizeof(name_str), cur_action);
 
@@ -579,20 +580,26 @@
         cur_command = get_next_command(cur_action, cur_command);
     }
 
-    if (!cur_command)
+    if (!cur_command) {
         return;
+    }
 
-    ret = cur_command->func(cur_command->nargs, cur_command->args);
+    int result = cur_command->func(cur_command->nargs, cur_command->args);
     if (klog_get_level() >= KLOG_INFO_LEVEL) {
-        for (i = 0; i < cur_command->nargs; i++) {
+        for (int i = 0; i < cur_command->nargs; i++) {
             strlcat(cmd_str, cur_command->args[i], sizeof(cmd_str));
             if (i < cur_command->nargs - 1) {
                 strlcat(cmd_str, " ", sizeof(cmd_str));
             }
         }
-        INFO("command '%s' action=%s status=%d (%s:%d)\n",
-             cmd_str, cur_action ? name_str : "", ret, cur_command->filename,
-             cur_command->line);
+        char source[256];
+        if (cur_command->filename) {
+            snprintf(source, sizeof(source), " (%s:%d)", cur_command->filename, cur_command->line);
+        } else {
+            *source = '\0';
+        }
+        INFO("Command '%s' action=%s%s returned %d took %.2fs\n",
+             cmd_str, cur_action ? name_str : "", source, result, t.duration());
     }
 }
 
@@ -928,40 +935,25 @@
     return 0;
 }
 
-static int audit_callback(void *data, security_class_t /*cls*/, char *buf, size_t len)
-{
+static int audit_callback(void *data, security_class_t /*cls*/, char *buf, size_t len) {
     snprintf(buf, len, "property=%s", !data ? "NULL" : (char *)data);
     return 0;
 }
 
-int log_callback(int type, const char *fmt, ...)
-{
-    int level;
-    va_list ap;
-    switch (type) {
-    case SELINUX_WARNING:
-        level = KLOG_WARNING_LEVEL;
-        break;
-    case SELINUX_INFO:
-        level = KLOG_INFO_LEVEL;
-        break;
-    default:
-        level = KLOG_ERROR_LEVEL;
-        break;
-    }
-    va_start(ap, fmt);
-    klog_vwrite(level, fmt, ap);
-    va_end(ap);
-    return 0;
-}
+static void selinux_initialize() {
+    Timer t;
 
-static void selinux_initialize(void)
-{
+    selinux_callback cb;
+    cb.func_log = selinux_klog_callback;
+    selinux_set_callback(SELINUX_CB_LOG, cb);
+    cb.func_audit = audit_callback;
+    selinux_set_callback(SELINUX_CB_AUDIT, cb);
+
     if (selinux_is_disabled()) {
         return;
     }
 
-    INFO("loading selinux policy\n");
+    INFO("Loading SELinux policy...\n");
     if (selinux_android_load_policy() < 0) {
         ERROR("SELinux: Failed to load policy; rebooting into recovery mode\n");
         android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
@@ -972,14 +964,18 @@
     bool is_enforcing = selinux_is_enforcing();
     INFO("SELinux: security_setenforce(%d)\n", is_enforcing);
     security_setenforce(is_enforcing);
+
+    NOTICE("(Initializing SELinux took %.2fs.)\n", t.duration());
 }
 
 int main(int argc, char** argv) {
-    if (!strcmp(basename(argv[0]), "ueventd"))
+    if (!strcmp(basename(argv[0]), "ueventd")) {
         return ueventd_main(argc, argv);
+    }
 
-    if (!strcmp(basename(argv[0]), "watchdogd"))
+    if (!strcmp(basename(argv[0]), "watchdogd")) {
         return watchdogd_main(argc, argv);
+    }
 
     // Clear the umask.
     umask(0);
@@ -1008,36 +1004,32 @@
     // to the outside world.
     open_devnull_stdio();
     klog_init();
+    klog_set_level(KLOG_NOTICE_LEVEL);
+
+    NOTICE("init started!\n");
+
     property_init();
 
+    // If arguments are passed both on the command line and in DT,
+    // properties set in DT always have priority over the command-line ones.
     process_kernel_dt();
-    /* in case one is passing arguments both on the command line and in DT
-     * Properties set in DT always have priority over the command-line ones
-     */
     process_kernel_cmdline();
 
-    /* now propogate the kernel variables to internal variables
-     * used by init as well as the current required properties
-     */
+    // Propogate the kernel variables to internal variables
+    // used by init as well as the current required properties.
     export_kernel_boot_props();
 
-    selinux_callback cb;
-    cb.func_log = log_callback;
-    selinux_set_callback(SELINUX_CB_LOG, cb);
-    cb.func_audit = audit_callback;
-    selinux_set_callback(SELINUX_CB_AUDIT, cb);
-
     selinux_initialize();
 
     // These directories were necessarily created before initial policy load
     // and therefore need their security context restored to the proper value.
     // This must happen before /dev is populated by ueventd.
+    INFO("Running restorecon...\n");
     restorecon("/dev");
     restorecon("/dev/socket");
     restorecon("/dev/__properties__");
     restorecon_recursive("/sys");
 
-    INFO("property init\n");
     property_load_boot_defaults();
 
     init_parse_config_file("/init.rc");
@@ -1049,7 +1041,7 @@
     queue_builtin_action(keychord_init_action, "keychord_init");
     queue_builtin_action(console_init_action, "console_init");
 
-    // Execute all the boot actions to get us started.
+    // Trigger all the boot actions to get us started.
     action_for_each_trigger("init", action_add_queue_tail);
 
     // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
diff --git a/init/init_parser.cpp b/init/init_parser.cpp
index 57eb299..294dc19 100644
--- a/init/init_parser.cpp
+++ b/init/init_parser.cpp
@@ -14,15 +14,16 @@
  * limitations under the License.
  */
 
+#include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdarg.h>
 #include <string.h>
-#include <stddef.h>
-#include <ctype.h>
+#include <unistd.h>
 
 #include "init.h"
 #include "parser.h"
@@ -351,7 +352,7 @@
     struct import* import = (struct import*) calloc(1, sizeof(struct import));
     import->filename = strdup(conf_file);
     list_add_tail(import_list, &import->list);
-    INFO("found import '%s', adding to import list", import->filename);
+    INFO("Added '%s' to import list\n", import->filename);
 }
 
 static void parse_new_section(struct parse_state *state, int kw,
@@ -439,6 +440,7 @@
 
 int init_parse_config_file(const char* path) {
     INFO("Parsing %s...\n", path);
+    Timer t;
     std::string data;
     if (!read_file(path, &data)) {
         return -1;
@@ -446,6 +448,8 @@
 
     parse_config(path, data);
     dump_parser_state();
+
+    NOTICE("(Parsing %s took %.2fs.)\n", path, t.duration());
     return 0;
 }
 
diff --git a/init/keychords.cpp b/init/keychords.cpp
index 2e996ea..27894a2 100644
--- a/init/keychords.cpp
+++ b/init/keychords.cpp
@@ -109,7 +109,7 @@
     if (!strcmp(adb_enabled, "running")) {
         svc = service_find_by_keychord(id);
         if (svc) {
-            INFO("starting service %s from keychord\n", svc->name);
+            INFO("Starting service %s from keychord\n", svc->name);
             service_start(svc, NULL);
         } else {
             ERROR("service for keychord %d not found\n", id);
diff --git a/init/log.cpp b/init/log.cpp
new file mode 100644
index 0000000..d32f2da
--- /dev/null
+++ b/init/log.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 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 <stdlib.h>
+#include <string.h>
+#include <sys/uio.h>
+
+#include <selinux/selinux.h>
+
+#include "log.h"
+
+static void init_klog_vwrite(int level, const char* fmt, va_list ap) {
+    static const char* tag = basename(getprogname());
+
+    char prefix[64];
+    snprintf(prefix, sizeof(prefix), "<%d>%s: ", level, tag);
+
+    char msg[512];
+    vsnprintf(msg, sizeof(msg), fmt, ap);
+
+    iovec iov[2];
+    iov[0].iov_base = prefix;
+    iov[0].iov_len = strlen(prefix);
+    iov[1].iov_base = msg;
+    iov[1].iov_len = strlen(msg);
+
+    klog_writev(level, iov, 2);
+}
+
+void init_klog_write(int level, const char* fmt, ...) {
+    va_list ap;
+    va_start(ap, fmt);
+    init_klog_vwrite(level, fmt, ap);
+    va_end(ap);
+}
+
+int selinux_klog_callback(int type, const char *fmt, ...) {
+    int level = KLOG_ERROR_LEVEL;
+    if (type == SELINUX_WARNING) {
+        level = KLOG_WARNING_LEVEL;
+    } else if (type == SELINUX_INFO) {
+        level = KLOG_INFO_LEVEL;
+    }
+    va_list ap;
+    va_start(ap, fmt);
+    init_klog_vwrite(level, fmt, ap);
+    va_end(ap);
+    return 0;
+}
diff --git a/init/log.h b/init/log.h
index e9cb65a..b804d1f 100644
--- a/init/log.h
+++ b/init/log.h
@@ -19,10 +19,11 @@
 
 #include <cutils/klog.h>
 
-#define ERROR(x...)   KLOG_ERROR("init", x)
-#define NOTICE(x...)  KLOG_NOTICE("init", x)
-#define INFO(x...)    KLOG_INFO("init", x)
+#define ERROR(x...)   init_klog_write(KLOG_ERROR_LEVEL, x)
+#define NOTICE(x...)  init_klog_write(KLOG_NOTICE_LEVEL, x)
+#define INFO(x...)    init_klog_write(KLOG_INFO_LEVEL, x)
 
-extern int log_callback(int type, const char *fmt, ...);
+void init_klog_write(int level, const char* fmt, ...) __printflike(2, 3);
+int selinux_klog_callback(int level, const char* fmt, ...) __printflike(2, 3);
 
 #endif
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 363b377..2fa81d4 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -54,7 +54,7 @@
 #define PERSISTENT_PROPERTY_DIR  "/data/property"
 
 static int persistent_properties_loaded = 0;
-static int property_area_inited = 0;
+static bool property_area_initialized = false;
 
 static int property_set_fd = -1;
 
@@ -63,34 +63,25 @@
     int fd;
 };
 
-static int init_workspace(workspace *w, size_t size)
-{
-    int fd = open(PROP_FILENAME, O_RDONLY | O_NOFOLLOW);
-    if (fd < 0)
-        return -1;
-
-    w->size = size;
-    w->fd = fd;
-    return 0;
-}
-
 static workspace pa_workspace;
 
-static int init_property_area(void)
-{
-    if (property_area_inited)
-        return -1;
+void property_init() {
+    if (property_area_initialized) {
+        return;
+    }
 
-    if(__system_property_area_init())
-        return -1;
+    property_area_initialized = true;
 
-    if(init_workspace(&pa_workspace, 0))
-        return -1;
+    if (__system_property_area_init()) {
+        return;
+    }
 
-    fcntl(pa_workspace.fd, F_SETFD, FD_CLOEXEC);
-
-    property_area_inited = 1;
-    return 0;
+    pa_workspace.size = 0;
+    pa_workspace.fd = open(PROP_FILENAME, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
+    if (pa_workspace.fd == -1) {
+        ERROR("Failed to open %s: %s\n", PROP_FILENAME, strerror(errno));
+        return;
+    }
 }
 
 static int check_mac_perms(const char *name, char *sctx)
@@ -419,12 +410,13 @@
  * Filter is used to decide which properties to load: NULL loads all keys,
  * "ro.foo.*" is a prefix match, and "ro.foo.bar" is an exact match.
  */
-static void load_properties_from_file(const char *fn, const char *filter)
-{
+static void load_properties_from_file(const char* filename, const char* filter) {
+    Timer t;
     std::string data;
-    if (read_file(fn, &data)) {
+    if (read_file(filename, &data)) {
         load_properties(&data[0], filter);
     }
+    NOTICE("(Loading properties from %s took %.2fs.)\n", filename, t.duration());
 }
 
 static void load_persistent_properties() {
@@ -485,19 +477,12 @@
     }
 }
 
-void property_init(void)
-{
-    init_property_area();
-}
-
-void property_load_boot_defaults(void)
-{
+void property_load_boot_defaults() {
     load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT, NULL);
 }
 
-int properties_inited(void)
-{
-    return property_area_inited;
+bool properties_initialized() {
+    return property_area_initialized;
 }
 
 static void load_override_properties() {
@@ -510,21 +495,18 @@
     }
 }
 
-
 /* When booting an encrypted system, /data is not mounted when the
  * property service is started, so any properties stored there are
  * not loaded.  Vold triggers init to load these properties once it
  * has mounted /data.
  */
-void load_persist_props(void)
-{
+void load_persist_props(void) {
     load_override_properties();
     /* Read persistent properties after all default values have been loaded. */
     load_persistent_properties();
 }
 
-void load_all_props(void)
-{
+void load_all_props() {
     load_properties_from_file(PROP_PATH_SYSTEM_BUILD, NULL);
     load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT, NULL);
     load_properties_from_file(PROP_PATH_VENDOR_BUILD, NULL);
@@ -537,12 +519,10 @@
     load_persistent_properties();
 }
 
-void start_property_service(void)
-{
-    int fd;
+void start_property_service() {
+    int fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0, NULL);
+    if (fd == -1) return;
 
-    fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0, NULL);
-    if(fd < 0) return;
     fcntl(fd, F_SETFD, FD_CLOEXEC);
     fcntl(fd, F_SETFL, O_NONBLOCK);
 
@@ -550,7 +530,6 @@
     property_set_fd = fd;
 }
 
-int get_property_set_fd()
-{
+int get_property_set_fd() {
     return property_set_fd;
 }
diff --git a/init/property_service.h b/init/property_service.h
index 6e7fc00..825a7dd 100644
--- a/init/property_service.h
+++ b/init/property_service.h
@@ -29,7 +29,7 @@
 void get_property_workspace(int *fd, int *sz);
 extern int __property_get(const char *name, char *value);
 extern int property_set(const char *name, const char *value);
-extern int properties_inited();
+extern bool properties_initialized();
 int get_property_set_fd(void);
 
 #ifndef __clang__
diff --git a/init/readme.txt b/init/readme.txt
index 4c8d0d3..630dd03 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -323,12 +323,11 @@
 
 Bootcharting
 ------------
-
 This version of init contains code to perform "bootcharting": generating log
 files that can be later processed by the tools provided by www.bootchart.org.
 
-On the emulator, use the new -bootchart <timeout> option to boot with
-bootcharting activated for <timeout> seconds.
+On the emulator, use the -bootchart <timeout> option to boot with bootcharting
+activated for <timeout> seconds.
 
 On a device, create /data/bootchart/start with a command like the following:
 
@@ -349,9 +348,13 @@
 bootchart command-line utility:
 
   sudo apt-get install pybootchartgui
-  ANDROID_SERIAL=<device serial number>
+  # grab-bootchart.sh uses $ANDROID_SERIAL.
   $ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh
 
+One thing to watch for is that the bootchart will show init as if it started
+running at 0s. You'll have to look at dmesg to work out when the kernel
+actually started init.
+
 
 Debugging init
 --------------
diff --git a/init/signal_handler.cpp b/init/signal_handler.cpp
index c428b96..8be4af5 100644
--- a/init/signal_handler.cpp
+++ b/init/signal_handler.cpp
@@ -18,18 +18,23 @@
 #include <fcntl.h>
 #include <signal.h>
 #include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/types.h>
 #include <sys/wait.h>
-#include <cutils/sockets.h>
+#include <unistd.h>
+
+#include <base/stringprintf.h>
 #include <cutils/android_reboot.h>
 #include <cutils/list.h>
+#include <cutils/sockets.h>
 
 #include "init.h"
 #include "log.h"
 #include "util.h"
 
+#define CRITICAL_CRASH_THRESHOLD    4       /* if we crash >4 times ... */
+#define CRITICAL_CRASH_WINDOW       (4*60)  /* ... in 4 minutes, goto recovery */
+
 static int signal_fd = -1;
 static int signal_recv_fd = -1;
 
@@ -37,8 +42,17 @@
     write(signal_fd, &s, 1);
 }
 
-#define CRITICAL_CRASH_THRESHOLD    4       /* if we crash >4 times ... */
-#define CRITICAL_CRASH_WINDOW       (4*60)  /* ... in 4 minutes, goto recovery */
+std::string DescribeStatus(int status) {
+    if (WIFEXITED(status)) {
+        return android::base::StringPrintf("exited with status %d", WEXITSTATUS(status));
+    } else if (WIFSIGNALED(status)) {
+        return android::base::StringPrintf("killed by signal %d", WTERMSIG(status));
+    } else if (WIFSTOPPED(status)) {
+        return android::base::StringPrintf("stopped by signal %d", WSTOPSIG(status));
+    } else {
+        return "state changed";
+    }
+}
 
 static int wait_for_one_process() {
     int status;
@@ -46,28 +60,26 @@
     if (pid <= 0) {
         return -1;
     }
-    INFO("waitpid returned pid %d, status = %08x\n", pid, status);
 
     service* svc = service_find_by_pid(pid);
+
+    std::string name;
+    if (svc) {
+        name = android::base::StringPrintf("Service '%s' (pid %d)", svc->name, pid);
+    } else {
+        name = android::base::StringPrintf("Untracked pid %d", pid);
+    }
+
+    NOTICE("%s %s\n", name.c_str(), DescribeStatus(status).c_str());
+
     if (!svc) {
-        if (WIFEXITED(status)) {
-            ERROR("untracked pid %d exited with status %d\n", pid, WEXITSTATUS(status));
-        } else if (WIFSIGNALED(status)) {
-            ERROR("untracked pid %d killed by signal %d\n", pid, WTERMSIG(status));
-        } else if (WIFSTOPPED(status)) {
-            ERROR("untracked pid %d stopped by signal %d\n", pid, WSTOPSIG(status));
-        } else {
-            ERROR("untracked pid %d state changed\n", pid);
-        }
         return 0;
     }
 
     // TODO: all the code from here down should be a member function on service.
 
-    NOTICE("process '%s', pid %d exited\n", svc->name, pid);
-
     if (!(svc->flags & SVC_ONESHOT) || (svc->flags & SVC_RESTART)) {
-        NOTICE("process '%s' killing any children in process group\n", svc->name);
+        NOTICE("Service '%s' (pid %d) killing any children in process group\n", svc->name, pid);
         kill(-pid, SIGKILL);
     }
 
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 5af6e3d..c63fdaa 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -14,16 +14,17 @@
  * limitations under the License.
  */
 
-#include <poll.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
 #include <ctype.h>
+#include <fcntl.h>
+#include <poll.h>
 #include <signal.h>
-#include <selinux/selinux.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
+#include <base/stringprintf.h>
 #include <private/android_filesystem_config.h>
+#include <selinux/selinux.h>
 
 #include "ueventd.h"
 #include "log.h"
@@ -34,11 +35,6 @@
 
 int ueventd_main(int argc, char **argv)
 {
-    struct pollfd ufd;
-    int nr;
-    char hardware[PROP_VALUE_MAX];
-    char tmp[32];
-
     /*
      * init sets the umask to 077 for forked processes. We need to
      * create files with exact permissions, without modification by
@@ -55,38 +51,35 @@
 
     open_devnull_stdio();
     klog_init();
-    if (LOG_UEVENTS) {
-        /* Ensure we're at a logging level that will show the events */
-        if (klog_get_level() < KLOG_INFO_LEVEL) {
-            klog_set_level(KLOG_INFO_LEVEL);
-        }
-    }
+    klog_set_level(KLOG_NOTICE_LEVEL);
 
-    union selinux_callback cb;
-    cb.func_log = log_callback;
+    NOTICE("ueventd started!\n");
+
+    selinux_callback cb;
+    cb.func_log = selinux_klog_callback;
     selinux_set_callback(SELINUX_CB_LOG, cb);
 
-    INFO("starting ueventd\n");
-
+    char hardware[PROP_VALUE_MAX];
     property_get("ro.hardware", hardware);
 
     ueventd_parse_config_file("/ueventd.rc");
-
-    snprintf(tmp, sizeof(tmp), "/ueventd.%s.rc", hardware);
-    ueventd_parse_config_file(tmp);
+    ueventd_parse_config_file(android::base::StringPrintf("/ueventd.%s.rc", hardware).c_str());
 
     device_init();
 
+    pollfd ufd;
     ufd.events = POLLIN;
     ufd.fd = get_device_fd();
 
-    while(1) {
+    while (true) {
         ufd.revents = 0;
-        nr = poll(&ufd, 1, -1);
-        if (nr <= 0)
+        int nr = poll(&ufd, 1, -1);
+        if (nr <= 0) {
             continue;
-        if (ufd.revents & POLLIN)
-               handle_device_fd();
+        }
+        if (ufd.revents & POLLIN) {
+            handle_device_fd();
+        }
     }
 
     return 0;
diff --git a/init/util.cpp b/init/util.cpp
index 8b238d4..3b49b30 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -258,22 +258,16 @@
     return -1;
 }
 
-/*
- * gettime() - returns the time in seconds of the system's monotonic clock or
- * zero on error.
- */
-time_t gettime(void)
-{
-    struct timespec ts;
-    int ret;
+time_t gettime() {
+    timespec now;
+    clock_gettime(CLOCK_MONOTONIC, &now);
+    return now.tv_sec;
+}
 
-    ret = clock_gettime(CLOCK_MONOTONIC, &ts);
-    if (ret < 0) {
-        ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno));
-        return 0;
-    }
-
-    return ts.tv_sec;
+uint64_t gettime_ns() {
+    timespec now;
+    clock_gettime(CLOCK_MONOTONIC, &now);
+    return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
 }
 
 int mkdir_recursive(const char *pathname, mode_t mode)
diff --git a/init/util.h b/init/util.h
index e0b3c69..8fec7a8 100644
--- a/init/util.h
+++ b/init/util.h
@@ -33,7 +33,22 @@
 bool read_file(const char* path, std::string* content);
 int write_file(const char* path, const char* content);
 
-time_t gettime(void);
+time_t gettime();
+uint64_t gettime_ns();
+
+class Timer {
+ public:
+  Timer() : t0(gettime_ns()) {
+  }
+
+  double duration() {
+    return static_cast<double>(gettime_ns() - t0) / 1000000000.0;
+  }
+
+ private:
+  uint64_t t0;
+};
+
 unsigned int decode_uid(const char *s);
 
 int mkdir_recursive(const char *pathname, mode_t mode);
diff --git a/init/watchdogd.cpp b/init/watchdogd.cpp
index 0790811..881a4df 100644
--- a/init/watchdogd.cpp
+++ b/init/watchdogd.cpp
@@ -27,52 +27,45 @@
 
 #define DEV_NAME "/dev/watchdog"
 
-int watchdogd_main(int argc, char **argv)
-{
-    int fd;
-    int ret;
-    int interval = 10;
-    int margin = 10;
-    int timeout;
-
+int watchdogd_main(int argc, char **argv) {
     open_devnull_stdio();
     klog_init();
+    klog_set_level(KLOG_NOTICE_LEVEL);
 
-    INFO("Starting watchdogd\n");
+    int interval = 10;
+    if (argc >= 2) interval = atoi(argv[1]);
 
-    if (argc >= 2)
-        interval = atoi(argv[1]);
+    int margin = 10;
+    if (argc >= 3) margin = atoi(argv[2]);
 
-    if (argc >= 3)
-        margin = atoi(argv[2]);
+    NOTICE("watchdogd started (interval %d, margin %d)!\n", interval, margin);
 
-    timeout = interval + margin;
-
-    fd = open(DEV_NAME, O_RDWR|O_CLOEXEC);
-    if (fd < 0) {
+    int fd = open(DEV_NAME, O_RDWR|O_CLOEXEC);
+    if (fd == -1) {
         ERROR("watchdogd: Failed to open %s: %s\n", DEV_NAME, strerror(errno));
         return 1;
     }
 
-    ret = ioctl(fd, WDIOC_SETTIMEOUT, &timeout);
+    int timeout = interval + margin;
+    int ret = ioctl(fd, WDIOC_SETTIMEOUT, &timeout);
     if (ret) {
         ERROR("watchdogd: Failed to set timeout to %d: %s\n", timeout, strerror(errno));
         ret = ioctl(fd, WDIOC_GETTIMEOUT, &timeout);
         if (ret) {
             ERROR("watchdogd: Failed to get timeout: %s\n", strerror(errno));
         } else {
-            if (timeout > margin)
+            if (timeout > margin) {
                 interval = timeout - margin;
-            else
+            } else {
                 interval = 1;
+            }
             ERROR("watchdogd: Adjusted interval to timeout returned by driver: timeout %d, interval %d, margin %d\n",
                   timeout, interval, margin);
         }
     }
 
-    while(1) {
+    while (true) {
         write(fd, "", 1);
         sleep(interval);
     }
 }
-
diff --git a/libbacktrace/Android.build.mk b/libbacktrace/Android.build.mk
index 7e1cd53..d7eaa68 100644
--- a/libbacktrace/Android.build.mk
+++ b/libbacktrace/Android.build.mk
@@ -67,10 +67,7 @@
 ifeq ($(build_type),host)
   # Only build if host builds are supported.
   ifeq ($(build_host),true)
-    LOCAL_CFLAGS += -Wno-extern-c-compat
-    ifneq ($($(module)_libc++),)
-      include external/libcxx/libcxx.mk
-    endif
+    LOCAL_CFLAGS += -Wno-extern-c-compat -fno-omit-frame-pointer
     include $(BUILD_HOST_$(build_target))
   endif
 endif
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 2c5e351..d890319 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -64,7 +64,7 @@
 endif
 
 
-# Static library for host
+# Shared and static library for host
 # ========================================================
 LOCAL_MODULE := libcutils
 LOCAL_SRC_FILES := $(commonSources) $(commonHostSources) dlmalloc_stubs.c
@@ -76,6 +76,16 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_HOST_STATIC_LIBRARY)
 
+include $(CLEAR_VARS)
+LOCAL_MODULE := libcutils
+LOCAL_SRC_FILES := $(commonSources) $(commonHostSources) dlmalloc_stubs.c
+LOCAL_SHARED_LIBRARIES := liblog
+ifneq ($(HOST_OS),windows)
+LOCAL_CFLAGS += -Werror
+endif
+LOCAL_MULTILIB := both
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_HOST_SHARED_LIBRARY)
 
 # Tests for host
 # ========================================================
diff --git a/libcutils/klog.c b/libcutils/klog.c
index fbb7b72..f574f08 100644
--- a/libcutils/klog.c
+++ b/libcutils/klog.c
@@ -14,13 +14,14 @@
  * limitations under the License.
  */
 
-#include <sys/stat.h>
-#include <sys/types.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
 
 #include <cutils/klog.h>
@@ -36,41 +37,36 @@
     klog_level = level;
 }
 
-void klog_init(void)
-{
-    static const char *name = "/dev/__kmsg__";
-
+void klog_init(void) {
     if (klog_fd >= 0) return; /* Already initialized */
 
+    static const char* name = "/dev/__kmsg__";
     if (mknod(name, S_IFCHR | 0600, (1 << 8) | 11) == 0) {
-        klog_fd = open(name, O_WRONLY);
-        if (klog_fd < 0)
-                return;
-        fcntl(klog_fd, F_SETFD, FD_CLOEXEC);
+        klog_fd = open(name, O_WRONLY | O_CLOEXEC);
         unlink(name);
     }
 }
 
 #define LOG_BUF_MAX 512
 
-void klog_vwrite(int level, const char *fmt, va_list ap)
-{
-    char buf[LOG_BUF_MAX];
-
+void klog_writev(int level, const struct iovec* iov, int iov_count) {
     if (level > klog_level) return;
     if (klog_fd < 0) klog_init();
     if (klog_fd < 0) return;
-
-    vsnprintf(buf, LOG_BUF_MAX, fmt, ap);
-    buf[LOG_BUF_MAX - 1] = 0;
-
-    write(klog_fd, buf, strlen(buf));
+    TEMP_FAILURE_RETRY(writev(klog_fd, iov, iov_count));
 }
 
-void klog_write(int level, const char *fmt, ...)
-{
+void klog_write(int level, const char* fmt, ...) {
+    char buf[LOG_BUF_MAX];
     va_list ap;
     va_start(ap, fmt);
-    klog_vwrite(level, fmt, ap);
+    vsnprintf(buf, sizeof(buf), fmt, ap);
     va_end(ap);
+
+    buf[LOG_BUF_MAX - 1] = 0;
+
+    struct iovec iov[1];
+    iov[0].iov_base = buf;
+    iov[0].iov_len = strlen(buf);
+    klog_writev(level, iov, 1);
 }
diff --git a/libprocessgroup/Android.mk b/libprocessgroup/Android.mk
index 051999a..ee6ba58 100644
--- a/libprocessgroup/Android.mk
+++ b/libprocessgroup/Android.mk
@@ -8,7 +8,6 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_CFLAGS := -Wall -Werror
 LOCAL_REQUIRED_MODULE := processgroup_cleanup
-include external/libcxx/libcxx.mk
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
diff --git a/libsync/tests/Android.mk b/libsync/tests/Android.mk
index ad20e50..9c9562a 100644
--- a/libsync/tests/Android.mk
+++ b/libsync/tests/Android.mk
@@ -17,7 +17,6 @@
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
-include external/libcxx/libcxx.mk
 LOCAL_CLANG := true
 LOCAL_MODULE := sync-unit-tests
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
diff --git a/libutils/Looper.cpp b/libutils/Looper.cpp
index d739f11..e69784d 100644
--- a/libutils/Looper.cpp
+++ b/libutils/Looper.cpp
@@ -21,6 +21,7 @@
 #include <fcntl.h>
 #include <limits.h>
 #include <inttypes.h>
+#include <sys/eventfd.h>
 
 
 namespace android {
@@ -71,28 +72,15 @@
         mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
         mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false),
         mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
-    int wakeFds[2];
-    int result = pipe(wakeFds);
-    LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);
-
-    mWakeReadPipeFd = wakeFds[0];
-    mWakeWritePipeFd = wakeFds[1];
-
-    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
-    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking.  errno=%d",
-            errno);
-
-    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
-    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking.  errno=%d",
-            errno);
+    mWakeEventFd = eventfd(0, EFD_NONBLOCK);
+    LOG_ALWAYS_FATAL_IF(mWakeEventFd < 0, "Could not make wake event fd.  errno=%d", errno);
 
     AutoMutex _l(mLock);
     rebuildEpollLocked();
 }
 
 Looper::~Looper() {
-    close(mWakeReadPipeFd);
-    close(mWakeWritePipeFd);
+    close(mWakeEventFd);
     if (mEpollFd >= 0) {
         close(mEpollFd);
     }
@@ -165,9 +153,9 @@
     struct epoll_event eventItem;
     memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
     eventItem.events = EPOLLIN;
-    eventItem.data.fd = mWakeReadPipeFd;
-    int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem);
-    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance.  errno=%d",
+    eventItem.data.fd = mWakeEventFd;
+    int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake event fd to epoll instance.  errno=%d",
             errno);
 
     for (size_t i = 0; i < mRequests.size(); i++) {
@@ -299,11 +287,11 @@
     for (int i = 0; i < eventCount; i++) {
         int fd = eventItems[i].data.fd;
         uint32_t epollEvents = eventItems[i].events;
-        if (fd == mWakeReadPipeFd) {
+        if (fd == mWakeEventFd) {
             if (epollEvents & EPOLLIN) {
                 awoken();
             } else {
-                ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
+                ALOGW("Ignoring unexpected epoll events 0x%x on wake event fd.", epollEvents);
             }
         } else {
             ssize_t requestIndex = mRequests.indexOfKey(fd);
@@ -418,12 +406,9 @@
     ALOGD("%p ~ wake", this);
 #endif
 
-    ssize_t nWrite;
-    do {
-        nWrite = write(mWakeWritePipeFd, "W", 1);
-    } while (nWrite == -1 && errno == EINTR);
-
-    if (nWrite != 1) {
+    uint64_t inc = 1;
+    ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t)));
+    if (nWrite != sizeof(uint64_t)) {
         if (errno != EAGAIN) {
             ALOGW("Could not write wake signal, errno=%d", errno);
         }
@@ -435,11 +420,8 @@
     ALOGD("%p ~ awoken", this);
 #endif
 
-    char buffer[16];
-    ssize_t nRead;
-    do {
-        nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
-    } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
+    uint64_t counter;
+    TEMP_FAILURE_RETRY(read(mWakeEventFd, &counter, sizeof(uint64_t)));
 }
 
 void Looper::pushResponse(int events, const Request& request) {
diff --git a/logd/libaudit.c b/logd/libaudit.c
index d00d579..cf76305 100644
--- a/logd/libaudit.c
+++ b/logd/libaudit.c
@@ -177,7 +177,7 @@
      */
     status.pid = pid;
     status.mask = AUDIT_STATUS_PID | AUDIT_STATUS_RATE_LIMIT;
-    status.rate_limit = 20; // audit entries per second
+    status.rate_limit = 5; // audit entries per second
 
     /* Let the kernel know this pid will be registering for audit events */
     rc = audit_send(fd, AUDIT_SET, &status, sizeof(status));
diff --git a/rootdir/init.environ.rc.in b/rootdir/init.environ.rc.in
index 0064790..b34ea01 100644
--- a/rootdir/init.environ.rc.in
+++ b/rootdir/init.environ.rc.in
@@ -5,7 +5,7 @@
     export ANDROID_ASSETS /system/app
     export ANDROID_DATA /data
     export ANDROID_STORAGE /storage
+    export EXTERNAL_STORAGE /sdcard
     export ASEC_MOUNTPOINT /mnt/asec
-    export LOOP_MOUNTPOINT /mnt/obb
     export BOOTCLASSPATH %BOOTCLASSPATH%
     export SYSTEMSERVERCLASSPATH %SYSTEMSERVERCLASSPATH%
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 2ff0d04..9fad0ed 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -26,14 +26,9 @@
 
     start ueventd
 
-    # create mountpoints
-    mkdir /mnt 0775 root system
-
 on init
     sysclktz 0
 
-    loglevel 3
-
     # Backward compatibility.
     symlink /system/etc /etc
     symlink /sys/kernel/debug /d
@@ -64,28 +59,29 @@
     mkdir /cache 0770 system cache
     mkdir /config 0500 root root
 
+    # Mount staging areas for devices managed by vold
     # See storage config details at http://source.android.com/tech/storage/
-    mkdir /mnt/shell 0700 shell shell
-    mkdir /mnt/media_rw 0700 media_rw media_rw
-    mkdir /storage 0751 root sdcard_r
+    mkdir /mnt 0755 root system
+    mount tmpfs tmpfs /mnt mode=0755,uid=0,gid=1000
+    restorecon_recursive /mnt
 
-    # Directory for putting things only root should see.
     mkdir /mnt/secure 0700 root root
+    mkdir /mnt/secure/asec 0700 root root
+    mkdir /mnt/asec 0755 root system
+    mkdir /mnt/obb 0755 root system
+    mkdir /mnt/media_rw 0750 root media_rw
+    mkdir /mnt/user 0755 root root
+    mkdir /mnt/user/0 0755 root root
 
-    # Directory for staging bindmounts
-    mkdir /mnt/secure/staging 0700 root root
+    # sdcard_r is GID 1028
+    mkdir /storage 0751 root sdcard_r
+    mount tmpfs tmpfs /storage mode=0751,uid=0,gid=1028
+    restorecon_recursive /storage
 
-    # Directory-target for where the secure container
-    # imagefile directory will be bind-mounted
-    mkdir /mnt/secure/asec  0700 root root
-
-    # Secure container public mount points.
-    mkdir /mnt/asec  0700 root system
-    mount tmpfs tmpfs /mnt/asec mode=0755,gid=1000
-
-    # Filesystem image public mount points.
-    mkdir /mnt/obb 0700 root system
-    mount tmpfs tmpfs /mnt/obb mode=0755,gid=1000
+    # Symlink to keep legacy apps working in multi-user world
+    mkdir /storage/self 0751 root sdcard_r
+    symlink /storage/self/primary /sdcard
+    symlink /mnt/user/0/primary /storage/self/primary
 
     # memory control cgroup
     mkdir /dev/memcg 0700 root system
@@ -237,6 +233,9 @@
     # We restorecon /data in case the userdata partition has been reset.
     restorecon /data
 
+    # Emulated internal storage area
+    mkdir /data/media 0770 media_rw media_rw
+
     # Start bootcharting as soon as possible after the data partition is
     # mounted to collect more data.
     mkdir /data/bootchart 0755 shell shell
diff --git a/run-as/run-as.c b/run-as/run-as.c
index cc05e63..368b8f1 100644
--- a/run-as/run-as.c
+++ b/run-as/run-as.c
@@ -15,22 +15,25 @@
 ** limitations under the License.
 */
 
-#define PROGNAME  "run-as"
-#define LOG_TAG   PROGNAME
+#define PROGNAME "run-as"
+#define LOG_TAG  PROGNAME
 
+#include <dirent.h>
+#include <errno.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/types.h>
+#include <sys/capability.h>
+#include <sys/cdefs.h>
 #include <sys/stat.h>
-#include <dirent.h>
-#include <errno.h>
-#include <unistd.h>
+#include <sys/types.h>
 #include <time.h>
-#include <stdarg.h>
+#include <unistd.h>
 
-#include <selinux/android.h>
 #include <private/android_filesystem_config.h>
+#include <selinux/android.h>
+
 #include "package.h"
 
 /*
@@ -83,37 +86,37 @@
  *  - Run the 'gdbserver' binary executable to allow native debugging
  */
 
-static void
-usage(void)
-{
-    const char*  str = "Usage: " PROGNAME " <package-name> <command> [<args>]\n\n";
-    write(1, str, strlen(str));
-    exit(1);
-}
-
-
-static void
+__noreturn static void
 panic(const char* format, ...)
 {
     va_list args;
+    int e = errno;
 
     fprintf(stderr, "%s: ", PROGNAME);
     va_start(args, format);
     vfprintf(stderr, format, args);
     va_end(args);
-    exit(1);
+    exit(e ? -e : 1);
 }
 
+static void
+usage(void)
+{
+    panic("Usage:\n    " PROGNAME " <package-name> <command> [<args>]\n");
+}
 
 int main(int argc, char **argv)
 {
     const char* pkgname;
     int myuid, uid, gid;
     PackageInfo info;
+    struct __user_cap_header_struct capheader;
+    struct __user_cap_data_struct capdata[2];
 
     /* check arguments */
-    if (argc < 2)
+    if (argc < 2) {
         usage();
+    }
 
     /* check userid of caller - must be 'shell' or 'root' */
     myuid = getuid();
@@ -121,29 +124,37 @@
         panic("only 'shell' or 'root' users can run this program\n");
     }
 
-    /* retrieve package information from system */
+    memset(&capheader, 0, sizeof(capheader));
+    memset(&capdata, 0, sizeof(capdata));
+    capheader.version = _LINUX_CAPABILITY_VERSION_3;
+    capdata[CAP_TO_INDEX(CAP_SETUID)].effective |= CAP_TO_MASK(CAP_SETUID);
+    capdata[CAP_TO_INDEX(CAP_SETGID)].effective |= CAP_TO_MASK(CAP_SETGID);
+    capdata[CAP_TO_INDEX(CAP_SETUID)].permitted |= CAP_TO_MASK(CAP_SETUID);
+    capdata[CAP_TO_INDEX(CAP_SETGID)].permitted |= CAP_TO_MASK(CAP_SETGID);
+
+    if (capset(&capheader, &capdata[0]) < 0) {
+        panic("Could not set capabilities: %s\n", strerror(errno));
+    }
+
+    /* retrieve package information from system (does setegid) */
     pkgname = argv[1];
     if (get_package_info(pkgname, &info) < 0) {
         panic("Package '%s' is unknown\n", pkgname);
-        return 1;
     }
 
     /* reject system packages */
     if (info.uid < AID_APP) {
         panic("Package '%s' is not an application\n", pkgname);
-        return 1;
     }
 
     /* reject any non-debuggable package */
     if (!info.isDebuggable) {
         panic("Package '%s' is not debuggable\n", pkgname);
-        return 1;
     }
 
     /* check that the data directory path is valid */
     if (check_data_path(info.dataDir, info.uid) < 0) {
         panic("Package '%s' has corrupt installation\n", pkgname);
-        return 1;
     }
 
     /* Ensure that we change all real/effective/saved IDs at the
@@ -152,38 +163,30 @@
     uid = gid = info.uid;
     if(setresgid(gid,gid,gid) || setresuid(uid,uid,uid)) {
         panic("Permission denied\n");
-        return 1;
+    }
+
+    /* Required if caller has uid and gid all non-zero */
+    memset(&capdata, 0, sizeof(capdata));
+    if (capset(&capheader, &capdata[0]) < 0) {
+        panic("Could not clear all capabilities: %s\n", strerror(errno));
     }
 
     if (selinux_android_setcontext(uid, 0, info.seinfo, pkgname) < 0) {
-        panic("Could not set SELinux security context:  %s\n", strerror(errno));
-        return 1;
+        panic("Could not set SELinux security context: %s\n", strerror(errno));
     }
 
     /* cd into the data directory */
-    {
-        int ret;
-        do {
-            ret = chdir(info.dataDir);
-        } while (ret < 0 && errno == EINTR);
-
-        if (ret < 0) {
-            panic("Could not cd to package's data directory: %s\n", strerror(errno));
-            return 1;
-        }
+    if (TEMP_FAILURE_RETRY(chdir(info.dataDir)) < 0) {
+        panic("Could not cd to package's data directory: %s\n", strerror(errno));
     }
 
     /* User specified command for exec. */
-    if (argc >= 3 ) {
-        if (execvp(argv[2], argv+2) < 0) {
-            panic("exec failed for %s Error:%s\n", argv[2], strerror(errno));
-            return -errno;
-        }
+    if ((argc >= 3) && (execvp(argv[2], argv+2) < 0)) {
+        panic("exec failed for %s: %s\n", argv[2], strerror(errno));
     }
 
     /* Default exec shell. */
     execlp("/system/bin/sh", "sh", NULL);
 
-    panic("exec failed\n");
-    return 1;
+    panic("exec failed: %s\n", strerror(errno));
 }
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 599236f..2cb41e5 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -471,6 +471,7 @@
         node->perm = PERM_ROOT;
         node->userid = strtoul(node->name, NULL, 10);
         node->gid = multiuser_get_uid(node->userid, AID_SDCARD_R);
+        node->mode = 0771;
         break;
     case PERM_ROOT:
         /* Assume masked off by default. */
@@ -741,7 +742,7 @@
          * places user_id at the top directory level, with the actual roots
          * just below that. Shared OBB path is also at top level. */
         fuse->root.perm = PERM_LEGACY_PRE_ROOT;
-        fuse->root.mode = 0771;
+        fuse->root.mode = 0711;
         fuse->root.gid = AID_SDCARD_R;
         fuse->package_to_appid = hashmapCreate(256, str_hash, str_icase_equals);
         fuse->uid_with_rw = hashmapCreate(128, int_hash, int_equals);
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index 9b57d59..4e54eb8 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -47,7 +47,6 @@
     iftop \
     ioctl \
     ionice \
-    load_policy \
     log \
     ls \
     lsof \
@@ -58,7 +57,6 @@
     prlimit \
     renice \
     restorecon \
-    route \
     sendevent \
     setprop \
     start \
@@ -102,6 +100,14 @@
 $(TOOLS_H):
 	$(transform-generated-source)
 
+$(LOCAL_PATH)/getevent.c: $(intermediates)/input.h-labels.h
+
+INPUT_H_LABELS_H := $(intermediates)/input.h-labels.h
+$(INPUT_H_LABELS_H): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
+$(INPUT_H_LABELS_H): PRIVATE_CUSTOM_TOOL = $(PRIVATE_LOCAL_PATH)/generate-input.h-labels.py > $@
+$(INPUT_H_LABELS_H): $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/generate-input.h-labels.py
+$(INPUT_H_LABELS_H):
+	$(transform-generated-source)
 
 # We only want 'r' on userdebug and eng builds.
 include $(CLEAR_VARS)
diff --git a/toolbox/generate-input.h-labels.py b/toolbox/generate-input.h-labels.py
new file mode 100755
index 0000000..ebb9588
--- /dev/null
+++ b/toolbox/generate-input.h-labels.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2015 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.
+#
+# pylint: disable=bad-indentation,bad-continuation
+
+import os
+import re
+
+input_prop_list = []
+ev_list = []
+syn_list = []
+key_list = []
+rel_list = []
+abs_list = []
+sw_list = []
+msc_list = []
+led_list = []
+rep_list = []
+snd_list = []
+mt_tool_list = []
+ff_status_list = []
+ff_list = []
+
+r = re.compile(r'#define\s+(\S+)\s+((?:0x)?\d+)')
+
+with open('bionic/libc/kernel/uapi/linux/input.h', 'r') as f:
+  for line in f:
+    m = r.match(line)
+    if m:
+      name = m.group(1)
+      if name.startswith("INPUT_PROP_"):
+        input_prop_list.append(name)
+      elif name.startswith("EV_"):
+        ev_list.append(name)
+      elif name.startswith("SYN_"):
+        syn_list.append(name)
+      elif name.startswith("KEY_") or name.startswith("BTN_"):
+        key_list.append(name)
+      elif name.startswith("REL_"):
+        rel_list.append(name)
+      elif name.startswith("ABS_"):
+        abs_list.append(name)
+      elif name.startswith("SW_"):
+        sw_list.append(name)
+      elif name.startswith("MSC_"):
+        msc_list.append(name)
+      elif name.startswith("LED_"):
+        led_list.append(name)
+      elif name.startswith("REP_"):
+        rep_list.append(name)
+      elif name.startswith("SND_"):
+        snd_list.append(name)
+      elif name.startswith("MT_TOOL_"):
+        mt_tool_list.append(name)
+      elif name.startswith("FF_STATUS_"):
+        ff_status_list.append(name)
+      elif name.startswith("FF_"):
+        ff_list.append(name)
+
+def Dump(struct_name, values):
+  print 'static struct label %s[] = {' % (struct_name)
+  for value in values:
+    print '    LABEL(%s),' % (value)
+  print '    LABEL_END,'
+  print '};'
+
+Dump("input_prop_labels", input_prop_list)
+Dump("ev_labels", ev_list)
+Dump("syn_labels", syn_list)
+Dump("key_labels", key_list)
+Dump("rel_labels", rel_list)
+Dump("abs_labels", abs_list)
+Dump("sw_labels", sw_list)
+Dump("msc_labels", msc_list)
+Dump("led_labels", led_list)
+Dump("rep_labels", rep_list)
+Dump("snd_labels", snd_list)
+Dump("mt_tool_labels", mt_tool_list)
+Dump("ff_status_labels", ff_status_list)
+Dump("ff_labels", ff_list)
diff --git a/toolbox/getevent.c b/toolbox/getevent.c
index c58eb5d..30053af 100644
--- a/toolbox/getevent.c
+++ b/toolbox/getevent.c
@@ -12,7 +12,25 @@
 #include <errno.h>
 #include <unistd.h>
 
-#include "getevent.h"
+struct label {
+    const char *name;
+    int value;
+};
+
+#define LABEL(constant) { #constant, constant }
+#define LABEL_END { NULL, -1 }
+
+static struct label key_value_labels[] = {
+        { "UP", 0 },
+        { "DOWN", 1 },
+        { "REPEAT", 2 },
+        LABEL_END,
+};
+
+#include "input.h-labels.h"
+
+#undef LABEL
+#undef LABEL_END
 
 static struct pollfd *ufds;
 static char **device_names;
diff --git a/toolbox/getevent.h b/toolbox/getevent.h
deleted file mode 100644
index 0482d04..0000000
--- a/toolbox/getevent.h
+++ /dev/null
@@ -1,727 +0,0 @@
-#include <linux/input.h>
-
-struct label {
-    const char *name;
-    int value;
-};
-
-#define LABEL(constant) { #constant, constant }
-#define LABEL_END { NULL, -1 }
-
-static struct label input_prop_labels[] = {
-        LABEL(INPUT_PROP_POINTER),
-        LABEL(INPUT_PROP_DIRECT),
-        LABEL(INPUT_PROP_BUTTONPAD),
-        LABEL(INPUT_PROP_SEMI_MT),
-        LABEL_END,
-};
-
-static struct label ev_labels[] = {
-        LABEL(EV_SYN),
-        LABEL(EV_KEY),
-        LABEL(EV_REL),
-        LABEL(EV_ABS),
-        LABEL(EV_MSC),
-        LABEL(EV_SW),
-        LABEL(EV_LED),
-        LABEL(EV_SND),
-        LABEL(EV_REP),
-        LABEL(EV_FF),
-        LABEL(EV_PWR),
-        LABEL(EV_FF_STATUS),
-        LABEL_END,
-};
-
-static struct label syn_labels[] = {
-        LABEL(SYN_REPORT),
-        LABEL(SYN_CONFIG),
-        LABEL(SYN_MT_REPORT),
-        LABEL(SYN_DROPPED),
-        LABEL_END,
-};
-
-static struct label key_labels[] = {
-        LABEL(KEY_RESERVED),
-        LABEL(KEY_ESC),
-        LABEL(KEY_1),
-        LABEL(KEY_2),
-        LABEL(KEY_3),
-        LABEL(KEY_4),
-        LABEL(KEY_5),
-        LABEL(KEY_6),
-        LABEL(KEY_7),
-        LABEL(KEY_8),
-        LABEL(KEY_9),
-        LABEL(KEY_0),
-        LABEL(KEY_MINUS),
-        LABEL(KEY_EQUAL),
-        LABEL(KEY_BACKSPACE),
-        LABEL(KEY_TAB),
-        LABEL(KEY_Q),
-        LABEL(KEY_W),
-        LABEL(KEY_E),
-        LABEL(KEY_R),
-        LABEL(KEY_T),
-        LABEL(KEY_Y),
-        LABEL(KEY_U),
-        LABEL(KEY_I),
-        LABEL(KEY_O),
-        LABEL(KEY_P),
-        LABEL(KEY_LEFTBRACE),
-        LABEL(KEY_RIGHTBRACE),
-        LABEL(KEY_ENTER),
-        LABEL(KEY_LEFTCTRL),
-        LABEL(KEY_A),
-        LABEL(KEY_S),
-        LABEL(KEY_D),
-        LABEL(KEY_F),
-        LABEL(KEY_G),
-        LABEL(KEY_H),
-        LABEL(KEY_J),
-        LABEL(KEY_K),
-        LABEL(KEY_L),
-        LABEL(KEY_SEMICOLON),
-        LABEL(KEY_APOSTROPHE),
-        LABEL(KEY_GRAVE),
-        LABEL(KEY_LEFTSHIFT),
-        LABEL(KEY_BACKSLASH),
-        LABEL(KEY_Z),
-        LABEL(KEY_X),
-        LABEL(KEY_C),
-        LABEL(KEY_V),
-        LABEL(KEY_B),
-        LABEL(KEY_N),
-        LABEL(KEY_M),
-        LABEL(KEY_COMMA),
-        LABEL(KEY_DOT),
-        LABEL(KEY_SLASH),
-        LABEL(KEY_RIGHTSHIFT),
-        LABEL(KEY_KPASTERISK),
-        LABEL(KEY_LEFTALT),
-        LABEL(KEY_SPACE),
-        LABEL(KEY_CAPSLOCK),
-        LABEL(KEY_F1),
-        LABEL(KEY_F2),
-        LABEL(KEY_F3),
-        LABEL(KEY_F4),
-        LABEL(KEY_F5),
-        LABEL(KEY_F6),
-        LABEL(KEY_F7),
-        LABEL(KEY_F8),
-        LABEL(KEY_F9),
-        LABEL(KEY_F10),
-        LABEL(KEY_NUMLOCK),
-        LABEL(KEY_SCROLLLOCK),
-        LABEL(KEY_KP7),
-        LABEL(KEY_KP8),
-        LABEL(KEY_KP9),
-        LABEL(KEY_KPMINUS),
-        LABEL(KEY_KP4),
-        LABEL(KEY_KP5),
-        LABEL(KEY_KP6),
-        LABEL(KEY_KPPLUS),
-        LABEL(KEY_KP1),
-        LABEL(KEY_KP2),
-        LABEL(KEY_KP3),
-        LABEL(KEY_KP0),
-        LABEL(KEY_KPDOT),
-        LABEL(KEY_ZENKAKUHANKAKU),
-        LABEL(KEY_102ND),
-        LABEL(KEY_F11),
-        LABEL(KEY_F12),
-        LABEL(KEY_RO),
-        LABEL(KEY_KATAKANA),
-        LABEL(KEY_HIRAGANA),
-        LABEL(KEY_HENKAN),
-        LABEL(KEY_KATAKANAHIRAGANA),
-        LABEL(KEY_MUHENKAN),
-        LABEL(KEY_KPJPCOMMA),
-        LABEL(KEY_KPENTER),
-        LABEL(KEY_RIGHTCTRL),
-        LABEL(KEY_KPSLASH),
-        LABEL(KEY_SYSRQ),
-        LABEL(KEY_RIGHTALT),
-        LABEL(KEY_LINEFEED),
-        LABEL(KEY_HOME),
-        LABEL(KEY_UP),
-        LABEL(KEY_PAGEUP),
-        LABEL(KEY_LEFT),
-        LABEL(KEY_RIGHT),
-        LABEL(KEY_END),
-        LABEL(KEY_DOWN),
-        LABEL(KEY_PAGEDOWN),
-        LABEL(KEY_INSERT),
-        LABEL(KEY_DELETE),
-        LABEL(KEY_MACRO),
-        LABEL(KEY_MUTE),
-        LABEL(KEY_VOLUMEDOWN),
-        LABEL(KEY_VOLUMEUP),
-        LABEL(KEY_POWER),
-        LABEL(KEY_KPEQUAL),
-        LABEL(KEY_KPPLUSMINUS),
-        LABEL(KEY_PAUSE),
-        LABEL(KEY_SCALE),
-        LABEL(KEY_KPCOMMA),
-        LABEL(KEY_HANGEUL),
-        LABEL(KEY_HANGUEL),
-        LABEL(KEY_HANJA),
-        LABEL(KEY_YEN),
-        LABEL(KEY_LEFTMETA),
-        LABEL(KEY_RIGHTMETA),
-        LABEL(KEY_COMPOSE),
-        LABEL(KEY_STOP),
-        LABEL(KEY_AGAIN),
-        LABEL(KEY_PROPS),
-        LABEL(KEY_UNDO),
-        LABEL(KEY_FRONT),
-        LABEL(KEY_COPY),
-        LABEL(KEY_OPEN),
-        LABEL(KEY_PASTE),
-        LABEL(KEY_FIND),
-        LABEL(KEY_CUT),
-        LABEL(KEY_HELP),
-        LABEL(KEY_MENU),
-        LABEL(KEY_CALC),
-        LABEL(KEY_SETUP),
-        LABEL(KEY_SLEEP),
-        LABEL(KEY_WAKEUP),
-        LABEL(KEY_FILE),
-        LABEL(KEY_SENDFILE),
-        LABEL(KEY_DELETEFILE),
-        LABEL(KEY_XFER),
-        LABEL(KEY_PROG1),
-        LABEL(KEY_PROG2),
-        LABEL(KEY_WWW),
-        LABEL(KEY_MSDOS),
-        LABEL(KEY_COFFEE),
-        LABEL(KEY_SCREENLOCK),
-        LABEL(KEY_DIRECTION),
-        LABEL(KEY_CYCLEWINDOWS),
-        LABEL(KEY_MAIL),
-        LABEL(KEY_BOOKMARKS),
-        LABEL(KEY_COMPUTER),
-        LABEL(KEY_BACK),
-        LABEL(KEY_FORWARD),
-        LABEL(KEY_CLOSECD),
-        LABEL(KEY_EJECTCD),
-        LABEL(KEY_EJECTCLOSECD),
-        LABEL(KEY_NEXTSONG),
-        LABEL(KEY_PLAYPAUSE),
-        LABEL(KEY_PREVIOUSSONG),
-        LABEL(KEY_STOPCD),
-        LABEL(KEY_RECORD),
-        LABEL(KEY_REWIND),
-        LABEL(KEY_PHONE),
-        LABEL(KEY_ISO),
-        LABEL(KEY_CONFIG),
-        LABEL(KEY_HOMEPAGE),
-        LABEL(KEY_REFRESH),
-        LABEL(KEY_EXIT),
-        LABEL(KEY_MOVE),
-        LABEL(KEY_EDIT),
-        LABEL(KEY_SCROLLUP),
-        LABEL(KEY_SCROLLDOWN),
-        LABEL(KEY_KPLEFTPAREN),
-        LABEL(KEY_KPRIGHTPAREN),
-        LABEL(KEY_NEW),
-        LABEL(KEY_REDO),
-        LABEL(KEY_F13),
-        LABEL(KEY_F14),
-        LABEL(KEY_F15),
-        LABEL(KEY_F16),
-        LABEL(KEY_F17),
-        LABEL(KEY_F18),
-        LABEL(KEY_F19),
-        LABEL(KEY_F20),
-        LABEL(KEY_F21),
-        LABEL(KEY_F22),
-        LABEL(KEY_F23),
-        LABEL(KEY_F24),
-        LABEL(KEY_PLAYCD),
-        LABEL(KEY_PAUSECD),
-        LABEL(KEY_PROG3),
-        LABEL(KEY_PROG4),
-        LABEL(KEY_DASHBOARD),
-        LABEL(KEY_SUSPEND),
-        LABEL(KEY_CLOSE),
-        LABEL(KEY_PLAY),
-        LABEL(KEY_FASTFORWARD),
-        LABEL(KEY_BASSBOOST),
-        LABEL(KEY_PRINT),
-        LABEL(KEY_HP),
-        LABEL(KEY_CAMERA),
-        LABEL(KEY_SOUND),
-        LABEL(KEY_QUESTION),
-        LABEL(KEY_EMAIL),
-        LABEL(KEY_CHAT),
-        LABEL(KEY_SEARCH),
-        LABEL(KEY_CONNECT),
-        LABEL(KEY_FINANCE),
-        LABEL(KEY_SPORT),
-        LABEL(KEY_SHOP),
-        LABEL(KEY_ALTERASE),
-        LABEL(KEY_CANCEL),
-        LABEL(KEY_BRIGHTNESSDOWN),
-        LABEL(KEY_BRIGHTNESSUP),
-        LABEL(KEY_MEDIA),
-        LABEL(KEY_SWITCHVIDEOMODE),
-        LABEL(KEY_KBDILLUMTOGGLE),
-        LABEL(KEY_KBDILLUMDOWN),
-        LABEL(KEY_KBDILLUMUP),
-        LABEL(KEY_SEND),
-        LABEL(KEY_REPLY),
-        LABEL(KEY_FORWARDMAIL),
-        LABEL(KEY_SAVE),
-        LABEL(KEY_DOCUMENTS),
-        LABEL(KEY_BATTERY),
-        LABEL(KEY_BLUETOOTH),
-        LABEL(KEY_WLAN),
-        LABEL(KEY_UWB),
-        LABEL(KEY_UNKNOWN),
-        LABEL(KEY_VIDEO_NEXT),
-        LABEL(KEY_VIDEO_PREV),
-        LABEL(KEY_BRIGHTNESS_CYCLE),
-        LABEL(KEY_BRIGHTNESS_ZERO),
-        LABEL(KEY_DISPLAY_OFF),
-        LABEL(KEY_WIMAX),
-        LABEL(KEY_RFKILL),
-        LABEL(BTN_0),
-        LABEL(BTN_1),
-        LABEL(BTN_2),
-        LABEL(BTN_3),
-        LABEL(BTN_4),
-        LABEL(BTN_5),
-        LABEL(BTN_6),
-        LABEL(BTN_7),
-        LABEL(BTN_8),
-        LABEL(BTN_9),
-        LABEL(BTN_LEFT),
-        LABEL(BTN_RIGHT),
-        LABEL(BTN_MIDDLE),
-        LABEL(BTN_SIDE),
-        LABEL(BTN_EXTRA),
-        LABEL(BTN_FORWARD),
-        LABEL(BTN_BACK),
-        LABEL(BTN_TASK),
-        LABEL(BTN_JOYSTICK),
-        LABEL(BTN_TRIGGER),
-        LABEL(BTN_THUMB),
-        LABEL(BTN_THUMB2),
-        LABEL(BTN_TOP),
-        LABEL(BTN_TOP2),
-        LABEL(BTN_PINKIE),
-        LABEL(BTN_BASE),
-        LABEL(BTN_BASE2),
-        LABEL(BTN_BASE3),
-        LABEL(BTN_BASE4),
-        LABEL(BTN_BASE5),
-        LABEL(BTN_BASE6),
-        LABEL(BTN_DEAD),
-        LABEL(BTN_A),
-        LABEL(BTN_B),
-        LABEL(BTN_C),
-        LABEL(BTN_X),
-        LABEL(BTN_Y),
-        LABEL(BTN_Z),
-        LABEL(BTN_TL),
-        LABEL(BTN_TR),
-        LABEL(BTN_TL2),
-        LABEL(BTN_TR2),
-        LABEL(BTN_SELECT),
-        LABEL(BTN_START),
-        LABEL(BTN_MODE),
-        LABEL(BTN_THUMBL),
-        LABEL(BTN_THUMBR),
-        LABEL(BTN_TOOL_PEN),
-        LABEL(BTN_TOOL_RUBBER),
-        LABEL(BTN_TOOL_BRUSH),
-        LABEL(BTN_TOOL_PENCIL),
-        LABEL(BTN_TOOL_AIRBRUSH),
-        LABEL(BTN_TOOL_FINGER),
-        LABEL(BTN_TOOL_MOUSE),
-        LABEL(BTN_TOOL_LENS),
-        LABEL(BTN_TOUCH),
-        LABEL(BTN_STYLUS),
-        LABEL(BTN_STYLUS2),
-        LABEL(BTN_TOOL_DOUBLETAP),
-        LABEL(BTN_TOOL_TRIPLETAP),
-        LABEL(BTN_TOOL_QUADTAP),
-        LABEL(BTN_GEAR_DOWN),
-        LABEL(BTN_GEAR_UP),
-        LABEL(KEY_OK),
-        LABEL(KEY_SELECT),
-        LABEL(KEY_GOTO),
-        LABEL(KEY_CLEAR),
-        LABEL(KEY_POWER2),
-        LABEL(KEY_OPTION),
-        LABEL(KEY_INFO),
-        LABEL(KEY_TIME),
-        LABEL(KEY_VENDOR),
-        LABEL(KEY_ARCHIVE),
-        LABEL(KEY_PROGRAM),
-        LABEL(KEY_CHANNEL),
-        LABEL(KEY_FAVORITES),
-        LABEL(KEY_EPG),
-        LABEL(KEY_PVR),
-        LABEL(KEY_MHP),
-        LABEL(KEY_LANGUAGE),
-        LABEL(KEY_TITLE),
-        LABEL(KEY_SUBTITLE),
-        LABEL(KEY_ANGLE),
-        LABEL(KEY_ZOOM),
-        LABEL(KEY_MODE),
-        LABEL(KEY_KEYBOARD),
-        LABEL(KEY_SCREEN),
-        LABEL(KEY_PC),
-        LABEL(KEY_TV),
-        LABEL(KEY_TV2),
-        LABEL(KEY_VCR),
-        LABEL(KEY_VCR2),
-        LABEL(KEY_SAT),
-        LABEL(KEY_SAT2),
-        LABEL(KEY_CD),
-        LABEL(KEY_TAPE),
-        LABEL(KEY_RADIO),
-        LABEL(KEY_TUNER),
-        LABEL(KEY_PLAYER),
-        LABEL(KEY_TEXT),
-        LABEL(KEY_DVD),
-        LABEL(KEY_AUX),
-        LABEL(KEY_MP3),
-        LABEL(KEY_AUDIO),
-        LABEL(KEY_VIDEO),
-        LABEL(KEY_DIRECTORY),
-        LABEL(KEY_LIST),
-        LABEL(KEY_MEMO),
-        LABEL(KEY_CALENDAR),
-        LABEL(KEY_RED),
-        LABEL(KEY_GREEN),
-        LABEL(KEY_YELLOW),
-        LABEL(KEY_BLUE),
-        LABEL(KEY_CHANNELUP),
-        LABEL(KEY_CHANNELDOWN),
-        LABEL(KEY_FIRST),
-        LABEL(KEY_LAST),
-        LABEL(KEY_AB),
-        LABEL(KEY_NEXT),
-        LABEL(KEY_RESTART),
-        LABEL(KEY_SLOW),
-        LABEL(KEY_SHUFFLE),
-        LABEL(KEY_BREAK),
-        LABEL(KEY_PREVIOUS),
-        LABEL(KEY_DIGITS),
-        LABEL(KEY_TEEN),
-        LABEL(KEY_TWEN),
-        LABEL(KEY_VIDEOPHONE),
-        LABEL(KEY_GAMES),
-        LABEL(KEY_ZOOMIN),
-        LABEL(KEY_ZOOMOUT),
-        LABEL(KEY_ZOOMRESET),
-        LABEL(KEY_WORDPROCESSOR),
-        LABEL(KEY_EDITOR),
-        LABEL(KEY_SPREADSHEET),
-        LABEL(KEY_GRAPHICSEDITOR),
-        LABEL(KEY_PRESENTATION),
-        LABEL(KEY_DATABASE),
-        LABEL(KEY_NEWS),
-        LABEL(KEY_VOICEMAIL),
-        LABEL(KEY_ADDRESSBOOK),
-        LABEL(KEY_MESSENGER),
-        LABEL(KEY_DISPLAYTOGGLE),
-        LABEL(KEY_SPELLCHECK),
-        LABEL(KEY_LOGOFF),
-        LABEL(KEY_DOLLAR),
-        LABEL(KEY_EURO),
-        LABEL(KEY_FRAMEBACK),
-        LABEL(KEY_FRAMEFORWARD),
-        LABEL(KEY_CONTEXT_MENU),
-        LABEL(KEY_MEDIA_REPEAT),
-        LABEL(KEY_10CHANNELSUP),
-        LABEL(KEY_10CHANNELSDOWN),
-        LABEL(KEY_IMAGES),
-        LABEL(KEY_DEL_EOL),
-        LABEL(KEY_DEL_EOS),
-        LABEL(KEY_INS_LINE),
-        LABEL(KEY_DEL_LINE),
-        LABEL(KEY_FN),
-        LABEL(KEY_FN_ESC),
-        LABEL(KEY_FN_F1),
-        LABEL(KEY_FN_F2),
-        LABEL(KEY_FN_F3),
-        LABEL(KEY_FN_F4),
-        LABEL(KEY_FN_F5),
-        LABEL(KEY_FN_F6),
-        LABEL(KEY_FN_F7),
-        LABEL(KEY_FN_F8),
-        LABEL(KEY_FN_F9),
-        LABEL(KEY_FN_F10),
-        LABEL(KEY_FN_F11),
-        LABEL(KEY_FN_F12),
-        LABEL(KEY_FN_1),
-        LABEL(KEY_FN_2),
-        LABEL(KEY_FN_D),
-        LABEL(KEY_FN_E),
-        LABEL(KEY_FN_F),
-        LABEL(KEY_FN_S),
-        LABEL(KEY_FN_B),
-        LABEL(KEY_BRL_DOT1),
-        LABEL(KEY_BRL_DOT2),
-        LABEL(KEY_BRL_DOT3),
-        LABEL(KEY_BRL_DOT4),
-        LABEL(KEY_BRL_DOT5),
-        LABEL(KEY_BRL_DOT6),
-        LABEL(KEY_BRL_DOT7),
-        LABEL(KEY_BRL_DOT8),
-        LABEL(KEY_BRL_DOT9),
-        LABEL(KEY_BRL_DOT10),
-        LABEL(KEY_NUMERIC_0),
-        LABEL(KEY_NUMERIC_1),
-        LABEL(KEY_NUMERIC_2),
-        LABEL(KEY_NUMERIC_3),
-        LABEL(KEY_NUMERIC_4),
-        LABEL(KEY_NUMERIC_5),
-        LABEL(KEY_NUMERIC_6),
-        LABEL(KEY_NUMERIC_7),
-        LABEL(KEY_NUMERIC_8),
-        LABEL(KEY_NUMERIC_9),
-        LABEL(KEY_NUMERIC_STAR),
-        LABEL(KEY_NUMERIC_POUND),
-        LABEL(KEY_CAMERA_FOCUS),
-        LABEL(KEY_WPS_BUTTON),
-        LABEL(KEY_TOUCHPAD_TOGGLE),
-        LABEL(KEY_TOUCHPAD_ON),
-        LABEL(KEY_TOUCHPAD_OFF),
-        LABEL(KEY_CAMERA_ZOOMIN),
-        LABEL(KEY_CAMERA_ZOOMOUT),
-        LABEL(KEY_CAMERA_UP),
-        LABEL(KEY_CAMERA_DOWN),
-        LABEL(KEY_CAMERA_LEFT),
-        LABEL(KEY_CAMERA_RIGHT),
-        LABEL(BTN_TRIGGER_HAPPY1),
-        LABEL(BTN_TRIGGER_HAPPY2),
-        LABEL(BTN_TRIGGER_HAPPY3),
-        LABEL(BTN_TRIGGER_HAPPY4),
-        LABEL(BTN_TRIGGER_HAPPY5),
-        LABEL(BTN_TRIGGER_HAPPY6),
-        LABEL(BTN_TRIGGER_HAPPY7),
-        LABEL(BTN_TRIGGER_HAPPY8),
-        LABEL(BTN_TRIGGER_HAPPY9),
-        LABEL(BTN_TRIGGER_HAPPY10),
-        LABEL(BTN_TRIGGER_HAPPY11),
-        LABEL(BTN_TRIGGER_HAPPY12),
-        LABEL(BTN_TRIGGER_HAPPY13),
-        LABEL(BTN_TRIGGER_HAPPY14),
-        LABEL(BTN_TRIGGER_HAPPY15),
-        LABEL(BTN_TRIGGER_HAPPY16),
-        LABEL(BTN_TRIGGER_HAPPY17),
-        LABEL(BTN_TRIGGER_HAPPY18),
-        LABEL(BTN_TRIGGER_HAPPY19),
-        LABEL(BTN_TRIGGER_HAPPY20),
-        LABEL(BTN_TRIGGER_HAPPY21),
-        LABEL(BTN_TRIGGER_HAPPY22),
-        LABEL(BTN_TRIGGER_HAPPY23),
-        LABEL(BTN_TRIGGER_HAPPY24),
-        LABEL(BTN_TRIGGER_HAPPY25),
-        LABEL(BTN_TRIGGER_HAPPY26),
-        LABEL(BTN_TRIGGER_HAPPY27),
-        LABEL(BTN_TRIGGER_HAPPY28),
-        LABEL(BTN_TRIGGER_HAPPY29),
-        LABEL(BTN_TRIGGER_HAPPY30),
-        LABEL(BTN_TRIGGER_HAPPY31),
-        LABEL(BTN_TRIGGER_HAPPY32),
-        LABEL(BTN_TRIGGER_HAPPY33),
-        LABEL(BTN_TRIGGER_HAPPY34),
-        LABEL(BTN_TRIGGER_HAPPY35),
-        LABEL(BTN_TRIGGER_HAPPY36),
-        LABEL(BTN_TRIGGER_HAPPY37),
-        LABEL(BTN_TRIGGER_HAPPY38),
-        LABEL(BTN_TRIGGER_HAPPY39),
-        LABEL(BTN_TRIGGER_HAPPY40),
-        LABEL_END,
-};
-
-static struct label rel_labels[] = {
-        LABEL(REL_X),
-        LABEL(REL_Y),
-        LABEL(REL_Z),
-        LABEL(REL_RX),
-        LABEL(REL_RY),
-        LABEL(REL_RZ),
-        LABEL(REL_HWHEEL),
-        LABEL(REL_DIAL),
-        LABEL(REL_WHEEL),
-        LABEL(REL_MISC),
-        LABEL_END,
-};
-
-static struct label abs_labels[] = {
-        LABEL(ABS_X),
-        LABEL(ABS_Y),
-        LABEL(ABS_Z),
-        LABEL(ABS_RX),
-        LABEL(ABS_RY),
-        LABEL(ABS_RZ),
-        LABEL(ABS_THROTTLE),
-        LABEL(ABS_RUDDER),
-        LABEL(ABS_WHEEL),
-        LABEL(ABS_GAS),
-        LABEL(ABS_BRAKE),
-        LABEL(ABS_HAT0X),
-        LABEL(ABS_HAT0Y),
-        LABEL(ABS_HAT1X),
-        LABEL(ABS_HAT1Y),
-        LABEL(ABS_HAT2X),
-        LABEL(ABS_HAT2Y),
-        LABEL(ABS_HAT3X),
-        LABEL(ABS_HAT3Y),
-        LABEL(ABS_PRESSURE),
-        LABEL(ABS_DISTANCE),
-        LABEL(ABS_TILT_X),
-        LABEL(ABS_TILT_Y),
-        LABEL(ABS_TOOL_WIDTH),
-        LABEL(ABS_VOLUME),
-        LABEL(ABS_MISC),
-        LABEL(ABS_MT_SLOT),
-        LABEL(ABS_MT_TOUCH_MAJOR),
-        LABEL(ABS_MT_TOUCH_MINOR),
-        LABEL(ABS_MT_WIDTH_MAJOR),
-        LABEL(ABS_MT_WIDTH_MINOR),
-        LABEL(ABS_MT_ORIENTATION),
-        LABEL(ABS_MT_POSITION_X),
-        LABEL(ABS_MT_POSITION_Y),
-        LABEL(ABS_MT_TOOL_TYPE),
-        LABEL(ABS_MT_BLOB_ID),
-        LABEL(ABS_MT_TRACKING_ID),
-        LABEL(ABS_MT_PRESSURE),
-        LABEL(ABS_MT_DISTANCE),
-        LABEL_END,
-};
-
-static struct label sw_labels[] = {
-        LABEL(SW_LID),
-        LABEL(SW_TABLET_MODE),
-        LABEL(SW_HEADPHONE_INSERT),
-        LABEL(SW_RFKILL_ALL),
-        LABEL(SW_RADIO),
-        LABEL(SW_MICROPHONE_INSERT),
-        LABEL(SW_DOCK),
-        LABEL(SW_LINEOUT_INSERT),
-        LABEL(SW_JACK_PHYSICAL_INSERT),
-        LABEL(SW_VIDEOOUT_INSERT),
-        LABEL(SW_CAMERA_LENS_COVER),
-        LABEL(SW_KEYPAD_SLIDE),
-        LABEL(SW_FRONT_PROXIMITY),
-        LABEL(SW_ROTATE_LOCK),
-        LABEL_END,
-};
-
-static struct label msc_labels[] = {
-        LABEL(MSC_SERIAL),
-        LABEL(MSC_PULSELED),
-        LABEL(MSC_GESTURE),
-        LABEL(MSC_RAW),
-        LABEL(MSC_SCAN),
-        LABEL_END,
-};
-
-static struct label led_labels[] = {
-        LABEL(LED_NUML),
-        LABEL(LED_CAPSL),
-        LABEL(LED_SCROLLL),
-        LABEL(LED_COMPOSE),
-        LABEL(LED_KANA),
-        LABEL(LED_SLEEP),
-        LABEL(LED_SUSPEND),
-        LABEL(LED_MUTE),
-        LABEL(LED_MISC),
-        LABEL(LED_MAIL),
-        LABEL(LED_CHARGING),
-        LABEL_END,
-};
-
-static struct label rep_labels[] = {
-        LABEL(REP_DELAY),
-        LABEL(REP_PERIOD),
-        LABEL_END,
-};
-
-static struct label snd_labels[] = {
-        LABEL(SND_CLICK),
-        LABEL(SND_BELL),
-        LABEL(SND_TONE),
-        LABEL_END,
-};
-
-#if 0
-static struct label id_labels[] = {
-        LABEL(ID_BUS),
-        LABEL(ID_VENDOR),
-        LABEL(ID_PRODUCT),
-        LABEL(ID_VERSION),
-        LABEL_END,
-};
-
-static struct label bus_labels[] = {
-        LABEL(BUS_PCI),
-        LABEL(BUS_ISAPNP),
-        LABEL(BUS_USB),
-        LABEL(BUS_HIL),
-        LABEL(BUS_BLUETOOTH),
-        LABEL(BUS_VIRTUAL),
-        LABEL(BUS_ISA),
-        LABEL(BUS_I8042),
-        LABEL(BUS_XTKBD),
-        LABEL(BUS_RS232),
-        LABEL(BUS_GAMEPORT),
-        LABEL(BUS_PARPORT),
-        LABEL(BUS_AMIGA),
-        LABEL(BUS_ADB),
-        LABEL(BUS_I2C),
-        LABEL(BUS_HOST),
-        LABEL(BUS_GSC),
-        LABEL(BUS_ATARI),
-        LABEL(BUS_SPI),
-        LABEL_END,
-};
-#endif
-
-static struct label mt_tool_labels[] = {
-        LABEL(MT_TOOL_FINGER),
-        LABEL(MT_TOOL_PEN),
-        LABEL(MT_TOOL_MAX),
-        LABEL_END,
-};
-
-static struct label ff_status_labels[] = {
-        LABEL(FF_STATUS_STOPPED),
-        LABEL(FF_STATUS_PLAYING),
-        LABEL(FF_STATUS_MAX),
-        LABEL_END,
-};
-
-static struct label ff_labels[] = {
-        LABEL(FF_RUMBLE),
-        LABEL(FF_PERIODIC),
-        LABEL(FF_CONSTANT),
-        LABEL(FF_SPRING),
-        LABEL(FF_FRICTION),
-        LABEL(FF_DAMPER),
-        LABEL(FF_INERTIA),
-        LABEL(FF_RAMP),
-        LABEL(FF_SQUARE),
-        LABEL(FF_TRIANGLE),
-        LABEL(FF_SINE),
-        LABEL(FF_SAW_UP),
-        LABEL(FF_SAW_DOWN),
-        LABEL(FF_CUSTOM),
-        LABEL(FF_GAIN),
-        LABEL(FF_AUTOCENTER),
-        LABEL_END,
-};
-
-static struct label key_value_labels[] = {
-        { "UP", 0 },
-        { "DOWN", 1 },
-        { "REPEAT", 2 },
-        LABEL_END,
-};
diff --git a/toolbox/load_policy.c b/toolbox/load_policy.c
deleted file mode 100644
index 90d48c4..0000000
--- a/toolbox/load_policy.c
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <selinux/selinux.h>
-
-int load_policy_main(int argc, char **argv)
-{
-    int fd, rc;
-    struct stat sb;
-    void *map;
-    const char *path;
-
-    if (argc != 2) {
-        fprintf(stderr, "usage:  %s policy-file\n", argv[0]);
-        exit(1);
-    }
-
-    path = argv[1];
-    fd = open(path, O_RDONLY);
-    if (fd < 0) {
-        fprintf(stderr, "Could not open %s:  %s\n", path, strerror(errno));
-        exit(2);
-    }
-
-    if (fstat(fd, &sb) < 0) {
-        fprintf(stderr, "Could not stat %s:  %s\n", path, strerror(errno));
-        exit(3);
-    }
-
-    map = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-    if (map == MAP_FAILED) {
-        fprintf(stderr, "Could not mmap %s:  %s\n", path, strerror(errno));
-        exit(4);
-    }
-
-    rc = security_load_policy(map, sb.st_size);
-    if (rc < 0) {
-        fprintf(stderr, "Could not load %s:  %s\n", path, strerror(errno));
-        exit(5);
-    }
-    munmap(map, sb.st_size);
-    close(fd);
-    exit(0);
-}
diff --git a/toolbox/newfs_msdos.c b/toolbox/newfs_msdos.c
index 01517fd..5b98a01 100644
--- a/toolbox/newfs_msdos.c
+++ b/toolbox/newfs_msdos.c
@@ -798,6 +798,7 @@
                         __unused int oflag,struct bpb *bpb)
 {
     struct hd_geometry geom;
+    u_long block_size;
 
     if (ioctl(fd, BLKSSZGET, &bpb->bps)) {
         fprintf(stderr, "Error getting bytes / sector (%s)\n", strerror(errno));
@@ -806,11 +807,18 @@
 
     ckgeom(fname, bpb->bps, "bytes/sector");
 
-    if (ioctl(fd, BLKGETSIZE, &bpb->bsec)) {
+    if (ioctl(fd, BLKGETSIZE, &block_size)) {
         fprintf(stderr, "Error getting blocksize (%s)\n", strerror(errno));
         exit(1);
     }
 
+    if (block_size > UINT32_MAX) {
+        fprintf(stderr, "Error blocksize too large: %lu\n", block_size);
+        exit(1);
+    }
+
+    bpb->bsec = (u_int)block_size;
+
     if (ioctl(fd, HDIO_GETGEO, &geom)) {
         fprintf(stderr, "Error getting gemoetry (%s) - trying sane values\n", strerror(errno));
         geom.heads = 64;
diff --git a/toolbox/route.c b/toolbox/route.c
deleted file mode 100644
index 3e10014..0000000
--- a/toolbox/route.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2009, The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name of Google, Inc. nor the names of its contributors
- *    may be used to endorse or promote products derived from this
- *    software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <linux/route.h>
-
-static inline int set_address(const char *address, struct sockaddr *sa) {
-    return inet_aton(address, &((struct sockaddr_in *)sa)->sin_addr);
-}
-
-/* current support the following routing entries */
-/* route add default dev wlan0 */
-/* route add default gw 192.168.1.1 dev wlan0 */
-/* route add -net 192.168.1.2 netmask 255.255.255.0 gw 192.168.1.1 */
-
-int route_main(int argc, char *argv[])
-{
-    struct rtentry rt = {
-        .rt_dst     = {.sa_family = AF_INET},
-        .rt_genmask = {.sa_family = AF_INET},
-        .rt_gateway = {.sa_family = AF_INET},
-    };
-
-    errno = EINVAL;
-    if (argc > 2 && !strcmp(argv[1], "add")) {
-        if (!strcmp(argv[2], "default")) {
-            /* route add default dev wlan0 */
-            if (argc > 4 && !strcmp(argv[3], "dev")) {
-                rt.rt_flags = RTF_UP;
-                rt.rt_dev = argv[4];
-                errno = 0;
-                goto apply;
-            }
-
-            /* route add default gw 192.168.1.1 dev wlan0 */
-            if (argc > 6 && !strcmp(argv[3], "gw") && !strcmp(argv[5], "dev")) {
-                rt.rt_flags = RTF_UP | RTF_GATEWAY;
-                rt.rt_dev = argv[6];
-                if (set_address(argv[4], &rt.rt_gateway)) {
-                    errno = 0;
-                }
-                goto apply;
-            }
-        }
-
-        /* route add -net 192.168.1.2 netmask 255.255.255.0 gw 192.168.1.1 */
-        if (argc > 7 && !strcmp(argv[2], "-net") &&
-                !strcmp(argv[4], "netmask")) {
-            if (!strcmp(argv[6], "gw")) {
-                rt.rt_flags = RTF_UP | RTF_GATEWAY;
-                if (set_address(argv[3], &rt.rt_dst) &&
-                    set_address(argv[5], &rt.rt_genmask) &&
-                    set_address(argv[7], &rt.rt_gateway)) {
-                    errno = 0;
-                }
-                goto apply;
-            } else if (!strcmp(argv[6], "dev")) {
-                rt.rt_flags = RTF_UP;
-                rt.rt_dev = argv[7];
-                if (set_address(argv[3], &rt.rt_dst) &&
-                    set_address(argv[5], &rt.rt_genmask)) {
-                    errno = 0;
-                }
-                goto apply;
-            }
-        }
-    }
-
-apply:
-    if (!errno) {
-        int s = socket(AF_INET, SOCK_DGRAM, 0);
-        if (s != -1 && (ioctl(s, SIOCADDRT, &rt) != -1 || errno == EEXIST)) {
-            return 0;
-        }
-    }
-    puts(strerror(errno));
-    return errno;
-}