am c24b98c7: (-s ours) Add a couple of useful string functions. (DO NOT MERGE)

* commit 'c24b98c7d8d9380f885bb6ea4055a34082353879':
  Add a couple of useful string functions. (DO NOT MERGE)
diff --git a/adb/Android.mk b/adb/Android.mk
index 50e28a6..80427b8 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -102,7 +102,6 @@
 
 LOCAL_SRC_FILES := \
 	adb.c \
-	backup_service.c \
 	fdevent.c \
 	transport.c \
 	transport_local.c \
diff --git a/adb/SERVICES.TXT b/adb/SERVICES.TXT
index 7f85dc3..63000f2 100644
--- a/adb/SERVICES.TXT
+++ b/adb/SERVICES.TXT
@@ -240,3 +240,20 @@
     This starts the file synchronisation service, used to implement "adb push"
     and "adb pull". Since this service is pretty complex, it will be detailed
     in a companion document named SYNC.TXT
+
+reverse:<forward-command>
+    This implements the 'adb reverse' feature, i.e. the ability to reverse
+    socket connections from a device to the host. <forward-command> is one
+    of the forwarding commands that are described above, as in:
+
+      list-forward
+      forward:<local>;<remote>
+      forward:norebind:<local>;<remote>
+      killforward-all
+      killforward:<local>
+
+    Note that in this case, <local> corresponds to the socket on the device
+    and <remote> corresponds to the socket on the host.
+
+    The output of reverse:list-forward is the same as host:list-forward
+    except that <serial> will be just 'host'.
diff --git a/adb/adb.c b/adb/adb.c
index 018dd3c..6d3a71b 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -318,7 +318,18 @@
 #endif
 }
 
-static void send_msg_with_okay(int fd, char* msg, size_t msglen) {
+#if !ADB_HOST
+static void send_msg_with_header(int fd, const char* msg, size_t msglen) {
+    char header[5];
+    if (msglen > 0xffff)
+        msglen = 0xffff;
+    snprintf(header, sizeof(header), "%04x", (unsigned)msglen);
+    writex(fd, header, 4);
+    writex(fd, msg, msglen);
+}
+#endif
+
+static void send_msg_with_okay(int fd, const char* msg, size_t msglen) {
     char header[9];
     if (msglen > 0xffff)
         msglen = 0xffff;
@@ -1427,6 +1438,120 @@
     return 0;
 }
 
+// Try to handle a network forwarding request.
+// This returns 1 on success, 0 on failure, and -1 to indicate this is not
+// a forwarding-related request.
+int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd)
+{
+    if (!strcmp(service, "list-forward")) {
+        // Create the list of forward redirections.
+        int buffer_size = format_listeners(NULL, 0);
+        // Add one byte for the trailing zero.
+        char* buffer = malloc(buffer_size + 1);
+        if (buffer == NULL) {
+            sendfailmsg(reply_fd, "not enough memory");
+            return 1;
+        }
+        (void) format_listeners(buffer, buffer_size + 1);
+#if ADB_HOST
+        send_msg_with_okay(reply_fd, buffer, buffer_size);
+#else
+        send_msg_with_header(reply_fd, buffer, buffer_size);
+#endif
+        free(buffer);
+        return 1;
+    }
+
+    if (!strcmp(service, "killforward-all")) {
+        remove_all_listeners();
+#if ADB_HOST
+        /* On the host: 1st OKAY is connect, 2nd OKAY is status */
+        adb_write(reply_fd, "OKAY", 4);
+#endif
+        adb_write(reply_fd, "OKAY", 4);
+        return 1;
+    }
+
+    if (!strncmp(service, "forward:",8) ||
+        !strncmp(service, "killforward:",12)) {
+        char *local, *remote, *err;
+        int r;
+        atransport *transport;
+
+        int createForward = strncmp(service, "kill", 4);
+        int no_rebind = 0;
+
+        local = strchr(service, ':') + 1;
+
+        // Handle forward:norebind:<local>... here
+        if (createForward && !strncmp(local, "norebind:", 9)) {
+            no_rebind = 1;
+            local = strchr(local, ':') + 1;
+        }
+
+        remote = strchr(local,';');
+
+        if (createForward) {
+            // Check forward: parameter format: '<local>;<remote>'
+            if(remote == 0) {
+                sendfailmsg(reply_fd, "malformed forward spec");
+                return 1;
+            }
+
+            *remote++ = 0;
+            if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) {
+                sendfailmsg(reply_fd, "malformed forward spec");
+                return 1;
+            }
+        } else {
+            // Check killforward: parameter format: '<local>'
+            if (local[0] == 0) {
+                sendfailmsg(reply_fd, "malformed forward spec");
+                return 1;
+            }
+        }
+
+        transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
+        if (!transport) {
+            sendfailmsg(reply_fd, err);
+            return 1;
+        }
+
+        if (createForward) {
+            r = install_listener(local, remote, transport, no_rebind);
+        } else {
+            r = remove_listener(local, transport);
+        }
+        if(r == 0) {
+#if ADB_HOST
+            /* On the host: 1st OKAY is connect, 2nd OKAY is status */
+            writex(reply_fd, "OKAY", 4);
+#endif
+            writex(reply_fd, "OKAY", 4);
+            return 1;
+        }
+
+        if (createForward) {
+            const char* message;
+            switch (r) {
+              case INSTALL_STATUS_CANNOT_BIND:
+                message = "cannot bind to socket";
+                break;
+              case INSTALL_STATUS_CANNOT_REBIND:
+                message = "cannot rebind existing socket";
+                break;
+              default:
+                message = "internal error";
+            }
+            sendfailmsg(reply_fd, message);
+        } else {
+            sendfailmsg(reply_fd, "cannot remove listener");
+        }
+        return 1;
+    }
+    return 0;
+}
+
 int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
 {
     atransport *transport = NULL;
@@ -1547,97 +1672,9 @@
     }
 #endif // ADB_HOST
 
-    if(!strcmp(service,"list-forward")) {
-        // Create the list of forward redirections.
-        int buffer_size = format_listeners(NULL, 0);
-        // Add one byte for the trailing zero.
-        char* buffer = malloc(buffer_size+1);
-        (void) format_listeners(buffer, buffer_size+1);
-        send_msg_with_okay(reply_fd, buffer, buffer_size);
-        free(buffer);
-        return 0;
-    }
-
-    if (!strcmp(service,"killforward-all")) {
-        remove_all_listeners();
-        adb_write(reply_fd, "OKAYOKAY", 8);
-        return 0;
-    }
-
-    if(!strncmp(service,"forward:",8) ||
-       !strncmp(service,"killforward:",12)) {
-        char *local, *remote, *err;
-        int r;
-        atransport *transport;
-
-        int createForward = strncmp(service,"kill",4);
-        int no_rebind = 0;
-
-        local = strchr(service, ':') + 1;
-
-        // Handle forward:norebind:<local>... here
-        if (createForward && !strncmp(local, "norebind:", 9)) {
-            no_rebind = 1;
-            local = strchr(local, ':') + 1;
-        }
-
-        remote = strchr(local,';');
-
-        if (createForward) {
-            // Check forward: parameter format: '<local>;<remote>'
-            if(remote == 0) {
-                sendfailmsg(reply_fd, "malformed forward spec");
-                return 0;
-            }
-
-            *remote++ = 0;
-            if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){
-                sendfailmsg(reply_fd, "malformed forward spec");
-                return 0;
-            }
-        } else {
-            // Check killforward: parameter format: '<local>'
-            if (local[0] == 0) {
-                sendfailmsg(reply_fd, "malformed forward spec");
-                return 0;
-            }
-        }
-
-        transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
-        if (!transport) {
-            sendfailmsg(reply_fd, err);
-            return 0;
-        }
-
-        if (createForward) {
-            r = install_listener(local, remote, transport, no_rebind);
-        } else {
-            r = remove_listener(local, transport);
-        }
-        if(r == 0) {
-                /* 1st OKAY is connect, 2nd OKAY is status */
-            writex(reply_fd, "OKAYOKAY", 8);
-            return 0;
-        }
-
-        if (createForward) {
-            const char* message;
-            switch (r) {
-              case INSTALL_STATUS_CANNOT_BIND:
-                message = "cannot bind to socket";
-                break;
-              case INSTALL_STATUS_CANNOT_REBIND:
-                message = "cannot rebind existing socket";
-                break;
-              default:
-                message = "internal error";
-            }
-            sendfailmsg(reply_fd, message);
-        } else {
-            sendfailmsg(reply_fd, "cannot remove listener");
-        }
-        return 0;
-    }
+    int ret = handle_forward_request(service, ttype, serial, reply_fd);
+    if (ret >= 0)
+      return ret - 1;
 
     if(!strncmp(service,"get-state",strlen("get-state"))) {
         transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
diff --git a/adb/adb.h b/adb/adb.h
index 6f5c93c..4704abb 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -323,12 +323,9 @@
 int       create_jdwp_connection_fd(int  jdwp_pid);
 #endif
 
+int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd);
+
 #if !ADB_HOST
-typedef enum {
-    BACKUP,
-    RESTORE
-} BackupOperation;
-int backup_service(BackupOperation operation, char* args);
 void framebuffer_service(int fd, void *cookie);
 void remount_service(int fd, void *cookie);
 #endif
@@ -416,7 +413,7 @@
 #  define  D(...)          ((void)0)
 #  define  DR(...)         ((void)0)
 #  define  ADB_TRACING     0
-#endif
+#endif /* ADB_TRACE */
 
 
 #if !DEBUG_PACKETS
@@ -474,6 +471,11 @@
 extern int HOST;
 extern int SHELL_EXIT_NOTIFY_FD;
 
+typedef enum {
+    SUBPROC_PTY = 0,
+    SUBPROC_RAW = 1,
+} subproc_mode;
+
 #define CHUNK_SIZE (64*1024)
 
 #if !ADB_HOST
diff --git a/adb/backup_service.c b/adb/backup_service.c
deleted file mode 100644
index 654e0f3..0000000
--- a/adb/backup_service.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2011 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 <unistd.h>
-#include <stdio.h>
-
-#include "sysdeps.h"
-
-#define TRACE_TAG  TRACE_ADB
-#include "adb.h"
-
-typedef struct {
-    pid_t pid;
-    int fd;
-} backup_harvest_params;
-
-// socketpair but do *not* mark as close_on_exec
-static int backup_socketpair(int sv[2]) {
-    int rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv );
-    if (rc < 0)
-        return -1;
-
-    return 0;
-}
-
-// harvest the child process then close the read end of the socketpair
-static void* backup_child_waiter(void* args) {
-    int status;
-    backup_harvest_params* params = (backup_harvest_params*) args;
-
-    waitpid(params->pid, &status, 0);
-    adb_close(params->fd);
-    free(params);
-    return NULL;
-}
-
-/* returns the data socket passing the backup data here for forwarding */
-int backup_service(BackupOperation op, char* args) {
-    pid_t pid;
-    int s[2];
-    char* operation;
-
-    // Command string depends on our invocation
-    if (op == BACKUP) {
-        operation = "backup";
-    } else {
-        operation = "restore";
-    }
-
-    D("backup_service(%s, %s)\n", operation, args);
-
-    // set up the pipe from the subprocess to here
-    // parent will read s[0]; child will write s[1]
-    if (backup_socketpair(s)) {
-        D("can't create backup/restore socketpair\n");
-        fprintf(stderr, "unable to create backup/restore socketpair\n");
-        return -1;
-    }
-
-    D("Backup/restore socket pair: (send=%d, receive=%d)\n", s[1], s[0]);
-    close_on_exec(s[0]);    // only the side we hold on to
-
-    // spin off the child process to run the backup command
-    pid = fork();
-    if (pid < 0) {
-        // failure
-        D("can't fork for %s\n", operation);
-        fprintf(stderr, "unable to fork for %s\n", operation);
-        adb_close(s[0]);
-        adb_close(s[1]);
-        return -1;
-    }
-
-    // Great, we're off and running.
-    if (pid == 0) {
-        // child -- actually run the backup here
-        char* p;
-        int argc;
-        char portnum[16];
-        char** bu_args;
-
-        // fixed args:  [0] is 'bu', [1] is the port number, [2] is the 'operation' string
-        argc = 3;
-        for (p = (char*)args; p && *p; ) {
-            argc++;
-            while (*p && *p != ':') p++;
-            if (*p == ':') p++;
-        }
-
-        bu_args = (char**) alloca(argc*sizeof(char*) + 1);
-
-        // run through again to build the argv array
-        argc = 0;
-        bu_args[argc++] = "bu";
-        snprintf(portnum, sizeof(portnum), "%d", s[1]);
-        bu_args[argc++] = portnum;
-        bu_args[argc++] = operation;
-        for (p = (char*)args; p && *p; ) {
-            bu_args[argc++] = p;
-            while (*p && *p != ':') p++;
-            if (*p == ':') {
-                *p = 0;
-                p++;
-            }
-        }
-        bu_args[argc] = NULL;
-
-        // Close the half of the socket that we don't care about, route 'bu's console
-        // to the output socket, and off we go
-        adb_close(s[0]);
-
-        // off we go
-        execvp("/system/bin/bu", (char * const *)bu_args);
-        // oops error - close up shop and go home
-        fprintf(stderr, "Unable to exec 'bu', bailing\n");
-        exit(-1);
-    } else {
-        adb_thread_t t;
-        backup_harvest_params* params;
-
-        // parent, i.e. adbd -- close the sending half of the socket
-        D("fork() returned pid %d\n", pid);
-        adb_close(s[1]);
-
-        // spin a thread to harvest the child process
-        params = (backup_harvest_params*) malloc(sizeof(backup_harvest_params));
-        params->pid = pid;
-        params->fd = s[0];
-        if (adb_thread_create(&t, backup_child_waiter, params)) {
-            adb_close(s[0]);
-            free(params);
-            D("Unable to create child harvester\n");
-            return -1;
-        }
-    }
-
-    // we'll be reading from s[0] as the data is sent by the child process
-    return s[0];
-}
diff --git a/adb/commandline.c b/adb/commandline.c
index a3eaf43..4f2d40f 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -137,6 +137,19 @@
         "                                 if <local> is already forwarded\n"
         "  adb forward --remove <local> - remove a specific forward socket connection\n"
         "  adb forward --remove-all     - remove all forward socket connections\n"
+        "  adb reverse --list           - list all reverse socket connections from device\n"
+        "  adb reverse <remote> <local> - reverse socket connections\n"
+        "                                 reverse specs are one of:\n"
+        "                                   tcp:<port>\n"
+        "                                   localabstract:<unix domain socket name>\n"
+        "                                   localreserved:<unix domain socket name>\n"
+        "                                   localfilesystem:<unix domain socket name>\n"
+        "  adb reverse --norebind <remote> <local>\n"
+        "                               - same as 'adb reverse <remote> <local>' but fails\n"
+        "                                 if <remote> is already reversed.\n"
+        "  adb reverse --remove <remote>\n"
+        "                               - remove a specific reversed socket connection\n"
+        "  adb reverse --remove-all     - remove all reversed socket connections from device\n"
         "  adb jdwp                     - list PIDs of processes hosting a JDWP transport\n"
         "  adb install [-l] [-r] [-d] [-s] [--algo <algorithm name> --key <hex-encoded key> --iv <hex-encoded iv>] <file>\n"
         "                               - push this package file to the device and install it\n"
@@ -274,8 +287,17 @@
     long total = 0;
 
     D("copy_to_file(%d -> %d)\n", inFd, outFd);
+#ifdef HAVE_TERMIO_H
+    if (inFd == STDIN_FILENO) {
+        stdin_raw_init(STDIN_FILENO);
+    }
+#endif
     for (;;) {
-        len = adb_read(inFd, buf, BUFSIZE);
+        if (inFd == STDIN_FILENO) {
+            len = unix_read(inFd, buf, BUFSIZE);
+        } else {
+            len = adb_read(inFd, buf, BUFSIZE);
+        }
         if (len == 0) {
             D("copy_to_file() : read 0 bytes; exiting\n");
             break;
@@ -288,9 +310,19 @@
             D("copy_to_file() : error %d\n", errno);
             break;
         }
-        adb_write(outFd, buf, len);
+        if (outFd == STDOUT_FILENO) {
+            fwrite(buf, 1, len, stdout);
+            fflush(stdout);
+        } else {
+            adb_write(outFd, buf, len);
+        }
         total += len;
     }
+#ifdef HAVE_TERMIO_H
+    if (inFd == STDIN_FILENO) {
+        stdin_raw_restore(STDIN_FILENO);
+    }
+#endif
     D("copy_to_file() finished after %lu bytes\n", total);
     free(buf);
 }
@@ -927,7 +959,6 @@
     return path_buf;
 }
 
-
 static void parse_push_pull_args(char **arg, int narg, char const **path1, char const **path2,
                                  int *show_progress, int *copy_attrs) {
     *show_progress = 0;
@@ -964,7 +995,6 @@
     int is_server = 0;
     int persist = 0;
     int r;
-    int quote;
     transport_type ttype = kTransportAny;
     char* serial = NULL;
     char* server_port_str = NULL;
@@ -1185,19 +1215,14 @@
             return r;
         }
 
-        snprintf(buf, sizeof buf, "shell:%s", argv[1]);
+        snprintf(buf, sizeof(buf), "shell:%s", argv[1]);
         argc -= 2;
         argv += 2;
-        while(argc-- > 0) {
-            strcat(buf, " ");
-
-            /* quote empty strings and strings with spaces */
-            quote = (**argv == 0 || strchr(*argv, ' '));
-            if (quote)
-                strcat(buf, "\"");
-            strcat(buf, *argv++);
-            if (quote)
-                strcat(buf, "\"");
+        while (argc-- > 0) {
+            char *quoted = dupAndQuote(*argv++);
+            strncat(buf, " ", sizeof(buf) - 1);
+            strncat(buf, quoted, sizeof(buf) - 1);
+            free(quoted);
         }
 
         for(;;) {
@@ -1229,6 +1254,36 @@
         }
     }
 
+    if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
+        int exec_in = !strcmp(argv[0], "exec-in");
+        int fd;
+
+        snprintf(buf, sizeof buf, "exec:%s", argv[1]);
+        argc -= 2;
+        argv += 2;
+        while (argc-- > 0) {
+            char *quoted = dupAndQuote(*argv++);
+            strncat(buf, " ", sizeof(buf) - 1);
+            strncat(buf, quoted, sizeof(buf) - 1);
+            free(quoted);
+        }
+
+        fd = adb_connect(buf);
+        if (fd < 0) {
+            fprintf(stderr, "error: %s\n", adb_error());
+            return -1;
+        }
+
+        if (exec_in) {
+            copy_to_file(STDIN_FILENO, fd);
+        } else {
+            copy_to_file(fd, STDOUT_FILENO);
+        }
+
+        adb_close(fd);
+        return 0;
+    }
+
     if(!strcmp(argv[0], "kill-server")) {
         int fd;
         fd = _adb_connect("host:kill");
@@ -1308,8 +1363,11 @@
         return 0;
     }
 
-    if(!strcmp(argv[0], "forward")) {
+    if(!strcmp(argv[0], "forward") ||
+       !strcmp(argv[0], "reverse"))
+    {
         char host_prefix[64];
+        char reverse = (char) !strcmp(argv[0], "reverse");
         char remove = 0;
         char remove_all = 0;
         char list = 0;
@@ -1338,15 +1396,19 @@
         }
 
         // Determine the <host-prefix> for this command.
-        if (serial) {
-            snprintf(host_prefix, sizeof host_prefix, "host-serial:%s",
-                    serial);
-        } else if (ttype == kTransportUsb) {
-            snprintf(host_prefix, sizeof host_prefix, "host-usb");
-        } else if (ttype == kTransportLocal) {
-            snprintf(host_prefix, sizeof host_prefix, "host-local");
+        if (reverse) {
+            snprintf(host_prefix, sizeof host_prefix, "reverse");
         } else {
-            snprintf(host_prefix, sizeof host_prefix, "host");
+            if (serial) {
+                snprintf(host_prefix, sizeof host_prefix, "host-serial:%s",
+                        serial);
+            } else if (ttype == kTransportUsb) {
+                snprintf(host_prefix, sizeof host_prefix, "host-usb");
+            } else if (ttype == kTransportLocal) {
+                snprintf(host_prefix, sizeof host_prefix, "host-local");
+            } else {
+                snprintf(host_prefix, sizeof host_prefix, "host");
+            }
         }
 
         // Implement forward --list
@@ -1734,6 +1796,8 @@
         } else if (!strcmp(argv[i], "--key")) {
             verify_apk = 0;
             i++;
+        } else if (!strcmp(argv[i], "--abi")) {
+            i++;
         }
     }
 
diff --git a/adb/framebuffer_service.c b/adb/framebuffer_service.c
index fa7fd98..8cbe840 100644
--- a/adb/framebuffer_service.c
+++ b/adb/framebuffer_service.c
@@ -61,7 +61,7 @@
     int w, h, f;
     int fds[2];
 
-    if (pipe(fds) < 0) goto pipefail;
+    if (pipe2(fds, O_CLOEXEC) < 0) goto pipefail;
 
     pid_t pid = fork();
     if (pid < 0) goto done;
diff --git a/adb/services.c b/adb/services.c
index e25a232..d1e8939 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -141,6 +141,17 @@
     adb_close(fd);
 }
 
+void reverse_service(int fd, void* arg)
+{
+    const char* command = arg;
+
+    if (handle_forward_request(command, kTransportAny, NULL, fd) < 0) {
+        sendfailmsg(fd, "not a reverse forwarding command");
+    }
+    free(arg);
+    adb_close(fd);
+}
+
 #endif
 
 static int create_service_thread(void (*func)(int, void *), void *cookie)
@@ -173,11 +184,26 @@
 }
 
 #if !ADB_HOST
-static int create_subprocess(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
+
+static void init_subproc_child()
 {
+    setsid();
+
+    // Set OOM adjustment to prevent killing
+    int fd = adb_open("/proc/self/oom_adj", O_WRONLY);
+    if (fd >= 0) {
+        adb_write(fd, "0", 1);
+        adb_close(fd);
+    } else {
+       D("adb: unable to update oom_adj\n");
+    }
+}
+
+static int create_subproc_pty(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
+{
+    D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
 #ifdef HAVE_WIN32_PROC
-    D("create_subprocess(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
-    fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
+    fprintf(stderr, "error: create_subproc_pty not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
     return -1;
 #else /* !HAVE_WIN32_PROC */
     char *devname;
@@ -204,47 +230,74 @@
         return -1;
     }
 
-    if(*pid == 0){
-        int pts;
+    if (*pid == 0) {
+        init_subproc_child();
 
-        setsid();
-
-        pts = unix_open(devname, O_RDWR);
-        if(pts < 0) {
+        int pts = unix_open(devname, O_RDWR);
+        if (pts < 0) {
             fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname);
             exit(-1);
         }
 
-        dup2(pts, 0);
-        dup2(pts, 1);
-        dup2(pts, 2);
+        dup2(pts, STDIN_FILENO);
+        dup2(pts, STDOUT_FILENO);
+        dup2(pts, STDERR_FILENO);
 
         adb_close(pts);
         adb_close(ptm);
 
-        // set OOM adjustment to zero
-        char text[64];
-        snprintf(text, sizeof text, "/proc/%d/oom_adj", getpid());
-        int fd = adb_open(text, O_WRONLY);
-        if (fd >= 0) {
-            adb_write(fd, "0", 1);
-            adb_close(fd);
-        } else {
-           D("adb: unable to open %s\n", text);
-        }
         execl(cmd, cmd, arg0, arg1, NULL);
         fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
                 cmd, strerror(errno), errno);
         exit(-1);
     } else {
-        // Don't set child's OOM adjustment to zero.
-        // Let the child do it itself, as sometimes the parent starts
-        // running before the child has a /proc/pid/oom_adj.
-        // """adb: unable to open /proc/644/oom_adj""" seen in some logs.
         return ptm;
     }
 #endif /* !HAVE_WIN32_PROC */
 }
+
+static int create_subproc_raw(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
+{
+    D("create_subproc_raw(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
+#ifdef HAVE_WIN32_PROC
+    fprintf(stderr, "error: create_subproc_raw not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
+    return -1;
+#else /* !HAVE_WIN32_PROC */
+
+    // 0 is parent socket, 1 is child socket
+    int sv[2];
+    if (unix_socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
+        printf("[ cannot create socket pair - %s ]\n", strerror(errno));
+        return -1;
+    }
+
+    *pid = fork();
+    if (*pid < 0) {
+        printf("- fork failed: %s -\n", strerror(errno));
+        adb_close(sv[0]);
+        adb_close(sv[1]);
+        return -1;
+    }
+
+    if (*pid == 0) {
+        adb_close(sv[0]);
+        init_subproc_child();
+
+        // Only hook up stdin/stdout; drop stderr
+        dup2(sv[1], STDIN_FILENO);
+        dup2(sv[1], STDOUT_FILENO);
+        adb_close(sv[1]);
+
+        execl(cmd, cmd, arg0, arg1, NULL);
+        fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
+                cmd, strerror(errno), errno);
+        exit(-1);
+    } else {
+        adb_close(sv[1]);
+        return sv[0];
+    }
+#endif /* !HAVE_WIN32_PROC */
+}
 #endif  /* !ABD_HOST */
 
 #if ADB_HOST
@@ -285,18 +338,32 @@
     }
 }
 
-static int create_subproc_thread(const char *name)
+static int create_subproc_thread(const char *name, const subproc_mode mode)
 {
     stinfo *sti;
     adb_thread_t t;
     int ret_fd;
-    pid_t pid;
-    if(name) {
-        ret_fd = create_subprocess(SHELL_COMMAND, "-c", name, &pid);
+    pid_t pid = -1;
+
+    const char *arg0, *arg1;
+    if (name == 0 || *name == 0) {
+        arg0 = "-"; arg1 = 0;
     } else {
-        ret_fd = create_subprocess(SHELL_COMMAND, "-", 0, &pid);
+        arg0 = "-c"; arg1 = name;
     }
-    D("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid);
+
+    switch (mode) {
+    case SUBPROC_PTY:
+        ret_fd = create_subproc_pty(SHELL_COMMAND, arg0, arg1, &pid);
+        break;
+    case SUBPROC_RAW:
+        ret_fd = create_subproc_raw(SHELL_COMMAND, arg0, arg1, &pid);
+        break;
+    default:
+        fprintf(stderr, "invalid subproc_mode %d\n", mode);
+        return -1;
+    }
+    D("create_subproc ret_fd=%d pid=%d\n", ret_fd, pid);
 
     sti = malloc(sizeof(stinfo));
     if(sti == 0) fatal("cannot allocate stinfo");
@@ -304,14 +371,14 @@
     sti->cookie = (void*) (uintptr_t) pid;
     sti->fd = ret_fd;
 
-    if(adb_thread_create( &t, service_bootstrap_func, sti)){
+    if (adb_thread_create(&t, service_bootstrap_func, sti)) {
         free(sti);
         adb_close(ret_fd);
-        printf("cannot create service thread\n");
+        fprintf(stderr, "cannot create service thread\n");
         return -1;
     }
 
-    D("service thread started, fd=%d pid=%d\n",ret_fd, pid);
+    D("service thread started, fd=%d pid=%d\n", ret_fd, pid);
     return ret_fd;
 }
 #endif
@@ -356,27 +423,35 @@
     } else if (!strncmp(name, "jdwp:", 5)) {
         ret = create_jdwp_connection_fd(atoi(name+5));
     } else if(!HOST && !strncmp(name, "shell:", 6)) {
-        if(name[6]) {
-            ret = create_subproc_thread(name + 6);
-        } else {
-            ret = create_subproc_thread(0);
-        }
+        ret = create_subproc_thread(name + 6, SUBPROC_PTY);
+    } else if(!HOST && !strncmp(name, "exec:", 5)) {
+        ret = create_subproc_thread(name + 5, SUBPROC_RAW);
     } else if(!strncmp(name, "sync:", 5)) {
         ret = create_service_thread(file_sync_service, NULL);
     } else if(!strncmp(name, "remount:", 8)) {
         ret = create_service_thread(remount_service, NULL);
     } else if(!strncmp(name, "reboot:", 7)) {
         void* arg = strdup(name + 7);
-        if(arg == 0) return -1;
+        if (arg == NULL) return -1;
         ret = create_service_thread(reboot_service, arg);
     } else if(!strncmp(name, "root:", 5)) {
         ret = create_service_thread(restart_root_service, NULL);
     } else if(!strncmp(name, "backup:", 7)) {
-        char* arg = strdup(name+7);
+        char* arg = strdup(name + 7);
         if (arg == NULL) return -1;
-        ret = backup_service(BACKUP, arg);
+        char* c = arg;
+        for (; *c != '\0'; c++) {
+            if (*c == ':')
+                *c = ' ';
+        }
+        char* cmd;
+        if (asprintf(&cmd, "/system/bin/bu backup %s", arg) != -1) {
+            ret = create_subproc_thread(cmd, SUBPROC_RAW);
+            free(cmd);
+        }
+        free(arg);
     } else if(!strncmp(name, "restore:", 8)) {
-        ret = backup_service(RESTORE, NULL);
+        ret = create_subproc_thread("/system/bin/bu restore", SUBPROC_RAW);
     } else if(!strncmp(name, "tcpip:", 6)) {
         int port;
         if (sscanf(name + 6, "%d", &port) == 0) {
@@ -385,6 +460,16 @@
         ret = create_service_thread(restart_tcp_service, (void *) (uintptr_t) port);
     } else if(!strncmp(name, "usb:", 4)) {
         ret = create_service_thread(restart_usb_service, NULL);
+    } else if (!strncmp(name, "reverse:", 8)) {
+        char* cookie = strdup(name + 8);
+        if (cookie == NULL) {
+            ret = -1;
+        } else {
+            ret = create_service_thread(reverse_service, cookie);
+            if (ret < 0) {
+                free(cookie);
+            }
+        }
 #endif
     }
     if (ret >= 0) {
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index 0357ced..c7e0ad5 100755
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -172,6 +172,8 @@
 #define VENDOR_ID_TI            0x0451
 // Toshiba's USB Vendor ID
 #define VENDOR_ID_TOSHIBA       0x0930
+// Unowhy's USB Vendor ID
+#define VENDOR_ID_UNOWHY        0x2A49
 // Vizio's USB Vendor ID
 #define VENDOR_ID_VIZIO         0xE040
 // Wacom's USB Vendor ID
@@ -257,6 +259,7 @@
     VENDOR_ID_TELEEPOCH,
     VENDOR_ID_TI,
     VENDOR_ID_TOSHIBA,
+    VENDOR_ID_UNOWHY,
     VENDOR_ID_VIZIO,
     VENDOR_ID_WACOM,
     VENDOR_ID_XIAOMI,
diff --git a/cpio/Android.mk b/cpio/Android.mk
index 5184463..575beb2 100644
--- a/cpio/Android.mk
+++ b/cpio/Android.mk
@@ -8,6 +8,8 @@
 
 LOCAL_MODULE := mkbootfs
 
+LOCAL_CFLAGS := -Werror
+
 include $(BUILD_HOST_EXECUTABLE)
 
 $(call dist-for-goals,dist_files,$(LOCAL_BUILT_MODULE))
diff --git a/cpio/mkbootfs.c b/cpio/mkbootfs.c
index 7d3740c..7175749 100644
--- a/cpio/mkbootfs.c
+++ b/cpio/mkbootfs.c
@@ -78,8 +78,9 @@
         s->st_mode = empty_path_config->mode | (s->st_mode & ~07777);
     } else {
         // Use the compiled-in fs_config() function.
-
-        fs_config(path, S_ISDIR(s->st_mode), &s->st_uid, &s->st_gid, &s->st_mode, &capabilities);
+        unsigned st_mode = s->st_mode;
+        fs_config(path, S_ISDIR(s->st_mode), &s->st_uid, &s->st_gid, &st_mode, &capabilities);
+        s->st_mode = (typeof(s->st_mode)) st_mode;
     }
 }
 
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index 8be3541..e4d7ecc 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -3,24 +3,24 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-	backtrace.cpp \
-	debuggerd.cpp \
-	getevent.cpp \
-	tombstone.cpp \
-	utility.cpp \
+    backtrace.cpp \
+    debuggerd.cpp \
+    getevent.cpp \
+    tombstone.cpp \
+    utility.cpp \
 
 LOCAL_SRC_FILES_arm    := arm/machine.cpp
 LOCAL_SRC_FILES_arm64  := arm64/machine.cpp
 LOCAL_SRC_FILES_mips   := mips/machine.cpp
+LOCAL_SRC_FILES_mips64 := mips/machine.cpp
 LOCAL_SRC_FILES_x86    := x86/machine.cpp
 LOCAL_SRC_FILES_x86_64 := x86_64/machine.cpp
 
-LOCAL_CONLYFLAGS := -std=gnu99
-LOCAL_CPPFLAGS := -std=gnu++11
-LOCAL_CFLAGS := \
-	-Wall \
-	-Wno-array-bounds \
-	-Werror
+LOCAL_CPPFLAGS := \
+    -std=gnu++11 \
+    -W -Wall -Wextra \
+    -Wunused \
+    -Werror \
 
 ifeq ($(ARCH_ARM_HAVE_VFP),true)
 LOCAL_CFLAGS_arm += -DWITH_VFP
@@ -30,11 +30,10 @@
 endif # ARCH_ARM_HAVE_VFP_D32
 
 LOCAL_SHARED_LIBRARIES := \
-	libbacktrace \
-	libc \
-	libcutils \
-	liblog \
-	libselinux \
+    libbacktrace \
+    libcutils \
+    liblog \
+    libselinux \
 
 include external/stlport/libstlport.mk
 
@@ -42,6 +41,7 @@
 LOCAL_MODULE_STEM_32 := debuggerd
 LOCAL_MODULE_STEM_64 := debuggerd64
 LOCAL_MULTILIB := both
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
 
 include $(BUILD_EXECUTABLE)
 
@@ -50,6 +50,7 @@
 LOCAL_SRC_FILES_arm    := arm/crashglue.S
 LOCAL_SRC_FILES_arm64  := arm64/crashglue.S
 LOCAL_SRC_FILES_mips   := mips/crashglue.S
+LOCAL_SRC_FILES_mips64 := mips/crashglue.S
 LOCAL_SRC_FILES_x86    := x86/crashglue.S
 LOCAL_SRC_FILES_x86_64 := x86_64/crashglue.S
 LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index 01845d9..61fd5f0 100755
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -56,6 +56,21 @@
 // Must match the path defined in NativeCrashListener.java
 #define NCRASH_SOCKET_PATH "/data/system/ndebugsocket"
 
+// Figure out the abi based on defined macros.
+#if defined(__arm__)
+#define ABI_STRING "arm"
+#elif defined(__aarch64__)
+#define ABI_STRING "arm64"
+#elif defined(__mips__)
+#define ABI_STRING "mips"
+#elif defined(__i386__)
+#define ABI_STRING "x86"
+#elif defined(__x86_64__)
+#define ABI_STRING "x86_64"
+#else
+#error "Unsupported ABI"
+#endif
+
 static bool signal_has_si_addr(int sig) {
   switch (sig) {
     case SIGBUS:
@@ -157,20 +172,16 @@
   return "?";
 }
 
-static void dump_revision_info(log_t* log) {
+static void dump_header_info(log_t* log) {
+  char fingerprint[PROPERTY_VALUE_MAX];
   char revision[PROPERTY_VALUE_MAX];
 
+  property_get("ro.build.fingerprint", fingerprint, "unknown");
   property_get("ro.revision", revision, "unknown");
 
-  _LOG(log, SCOPE_AT_FAULT, "Revision: '%s'\n", revision);
-}
-
-static void dump_build_info(log_t* log) {
-  char fingerprint[PROPERTY_VALUE_MAX];
-
-  property_get("ro.build.fingerprint", fingerprint, "unknown");
-
   _LOG(log, SCOPE_AT_FAULT, "Build fingerprint: '%s'\n", fingerprint);
+  _LOG(log, SCOPE_AT_FAULT, "Revision: '%s'\n", revision);
+  _LOG(log, SCOPE_AT_FAULT, "ABI: '%s'\n", ABI_STRING);
 }
 
 static void dump_signal_info(log_t* log, pid_t tid, int signal, int si_code) {
@@ -577,7 +588,6 @@
 static void dump_logs(log_t* log, pid_t pid, unsigned int tail) {
   dump_log_file(log, pid, "system", tail);
   dump_log_file(log, pid, "main", tail);
-  dump_log_file(log, pid, "events", tail);
 }
 
 static void dump_abort_message(Backtrace* backtrace, log_t* log, uintptr_t address) {
@@ -627,8 +637,7 @@
 
   _LOG(log, SCOPE_AT_FAULT,
        "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
-  dump_build_info(log);
-  dump_revision_info(log);
+  dump_header_info(log);
   dump_thread_info(log, pid, tid, SCOPE_AT_FAULT);
   if (signal) {
     dump_signal_info(log, tid, signal, si_code);
diff --git a/debuggerd/x86/machine.cpp b/debuggerd/x86/machine.cpp
index 141f19a..bcc217e 100644
--- a/debuggerd/x86/machine.cpp
+++ b/debuggerd/x86/machine.cpp
@@ -25,7 +25,7 @@
 #include "../utility.h"
 #include "../machine.h"
 
-void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
+void dump_memory_and_code(log_t*, pid_t, int) {
 }
 
 void dump_registers(log_t* log, pid_t tid, int scope_flags) {
diff --git a/debuggerd/x86_64/machine.cpp b/debuggerd/x86_64/machine.cpp
index 406851a..c8c7aa9 100755
--- a/debuggerd/x86_64/machine.cpp
+++ b/debuggerd/x86_64/machine.cpp
@@ -27,7 +27,7 @@
 #include "../utility.h"
 #include "../machine.h"
 
-void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
+void dump_memory_and_code(log_t*, pid_t, int) {
 }
 
 void dump_registers(log_t* log, pid_t tid, int scope_flags) {
diff --git a/fastbootd/transport.c b/fastbootd/transport.c
index ce8f9d0..9a16fd7 100644
--- a/fastbootd/transport.c
+++ b/fastbootd/transport.c
@@ -55,7 +55,7 @@
     ftruncate(fd, len);
 
     buffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-    if (buffer == NULL) {
+    if (buffer == MAP_FAILED) {
         D(ERR, "mmap(%zu) failed: %d %s", len, errno, strerror(errno));
         goto err;
     }
diff --git a/include/android/log.h b/include/android/log.h
index f5b1900..ad36bd2 100644
--- a/include/android/log.h
+++ b/include/android/log.h
@@ -98,8 +98,12 @@
  */
 int __android_log_print(int prio, const char *tag,  const char *fmt, ...)
 #if defined(__GNUC__)
+#if __USE_MINGW_ANSI_STDIO
+    __attribute__ ((format(gnu_printf, 3, 4)))
+#else
     __attribute__ ((format(printf, 3, 4)))
 #endif
+#endif
     ;
 
 /*
@@ -117,8 +121,12 @@
                           const char *fmt, ...)
 #if defined(__GNUC__)
     __attribute__ ((noreturn))
+#if __USE_MINGW_ANSI_STDIO
+    __attribute__ ((format(gnu_printf, 3, 4)))
+#else
     __attribute__ ((format(printf, 3, 4)))
 #endif
+#endif
     ;
 
 #ifdef __cplusplus
diff --git a/include/backtrace/BacktraceMap.h b/include/backtrace/BacktraceMap.h
index 13083bd..c717f09 100644
--- a/include/backtrace/BacktraceMap.h
+++ b/include/backtrace/BacktraceMap.h
@@ -18,6 +18,7 @@
 #define _BACKTRACE_BACKTRACE_MAP_H
 
 #include <stdint.h>
+#include <sys/types.h>
 #ifdef USE_MINGW
 // MINGW does not define these constants.
 #define PROT_NONE 0
diff --git a/include/cutils/bitops.h b/include/cutils/bitops.h
index c26dc54..045830d 100644
--- a/include/cutils/bitops.h
+++ b/include/cutils/bitops.h
@@ -59,7 +59,7 @@
 static inline int bitmask_ffz(unsigned int *bitmask, int num_bits)
 {
     int bit, result;
-    unsigned int i;
+    size_t i;
 
     for (i = 0; i < BITS_TO_WORDS(num_bits); i++) {
         bit = ffs(~bitmask[i]);
@@ -77,7 +77,7 @@
 
 static inline int bitmask_weight(unsigned int *bitmask, int num_bits)
 {
-    int i;
+    size_t i;
     int weight = 0;
 
     for (i = 0; i < BITS_TO_WORDS(num_bits); i++)
diff --git a/include/cutils/fs.h b/include/cutils/fs.h
index d1d4cf2..70f0b92 100644
--- a/include/cutils/fs.h
+++ b/include/cutils/fs.h
@@ -18,6 +18,7 @@
 #define __CUTILS_FS_H
 
 #include <sys/types.h>
+#include <unistd.h>
 
 /*
  * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
diff --git a/include/cutils/list.h b/include/cutils/list.h
index 945729a..4ba2cfd 100644
--- a/include/cutils/list.h
+++ b/include/cutils/list.h
@@ -44,10 +44,10 @@
 #define list_for_each_reverse(node, list) \
     for (node = (list)->prev; node != (list); node = node->prev)
 
-#define list_for_each_safe(node, next, list) \
-    for (node = (list)->next, next = node->next; \
+#define list_for_each_safe(node, n, list) \
+    for (node = (list)->next, n = node->next; \
          node != (list); \
-         node = next, next = node->next)
+         node = n, n = node->next)
 
 static inline void list_init(struct listnode *node)
 {
@@ -63,6 +63,14 @@
     head->prev = item;
 }
 
+static inline void list_add_head(struct listnode *head, struct listnode *item)
+{
+    item->next = head->next;
+    item->prev = head;
+    head->next->prev = item;
+    head->next = item;
+}
+
 static inline void list_remove(struct listnode *item)
 {
     item->next->prev = item->prev;
diff --git a/include/cutils/trace.h b/include/cutils/trace.h
index dbd5e25..fd9bc6a 100644
--- a/include/cutils/trace.h
+++ b/include/cutils/trace.h
@@ -20,6 +20,7 @@
 #include <inttypes.h>
 #include <stdbool.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <sys/cdefs.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -68,7 +69,8 @@
 #define ATRACE_TAG_RESOURCES        (1<<13)
 #define ATRACE_TAG_DALVIK           (1<<14)
 #define ATRACE_TAG_RS               (1<<15)
-#define ATRACE_TAG_LAST             ATRACE_TAG_RS
+#define ATRACE_TAG_BIONIC           (1<<16)
+#define ATRACE_TAG_LAST             ATRACE_TAG_BIONIC
 
 // Reserved for initialization.
 #define ATRACE_TAG_NOT_READY        (1LL<<63)
diff --git a/include/log/log_read.h b/include/log/log_read.h
index 54d71a4..946711a 100644
--- a/include/log/log_read.h
+++ b/include/log/log_read.h
@@ -67,7 +67,8 @@
     // timespec
     bool operator== (const timespec &T) const
     {
-        return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec);
+        return (tv_sec == static_cast<uint32_t>(T.tv_sec))
+            && (tv_nsec == static_cast<uint32_t>(T.tv_nsec));
     }
     bool operator!= (const timespec &T) const
     {
@@ -75,8 +76,9 @@
     }
     bool operator< (const timespec &T) const
     {
-        return (tv_sec < T.tv_sec)
-            || ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec));
+        return (tv_sec < static_cast<uint32_t>(T.tv_sec))
+            || ((tv_sec == static_cast<uint32_t>(T.tv_sec))
+                && (tv_nsec < static_cast<uint32_t>(T.tv_nsec)));
     }
     bool operator>= (const timespec &T) const
     {
@@ -84,8 +86,9 @@
     }
     bool operator> (const timespec &T) const
     {
-        return (tv_sec > T.tv_sec)
-            || ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec));
+        return (tv_sec > static_cast<uint32_t>(T.tv_sec))
+            || ((tv_sec == static_cast<uint32_t>(T.tv_sec))
+                && (tv_nsec > static_cast<uint32_t>(T.tv_nsec)));
     }
     bool operator<= (const timespec &T) const
     {
diff --git a/include/log/logger.h b/include/log/logger.h
index ed39c4f..53be1d3 100644
--- a/include/log/logger.h
+++ b/include/log/logger.h
@@ -62,9 +62,8 @@
 
 /*
  * The maximum size of the log entry payload that can be
- * written to the kernel logger driver. An attempt to write
- * more than this amount to /dev/log/* will result in a
- * truncated log entry.
+ * written to the logger. An attempt to write more than
+ * this amount will result in a truncated log entry.
  */
 #define LOGGER_ENTRY_MAX_PAYLOAD	4076
 
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index baa012d..db44f4b 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -77,6 +77,7 @@
 #define AID_SDCARD_AV     1034  /* external storage audio/video access */
 #define AID_SDCARD_ALL    1035  /* access all users external storage */
 #define AID_LOGD          1036  /* log daemon */
+#define AID_SHARED_RELRO  1037  /* creator of shared GNU RELRO files */
 
 #define AID_SHELL         2000  /* adb and debug shell user */
 #define AID_CACHE         2001  /* cache access */
@@ -93,6 +94,7 @@
 #define AID_NET_BW_ACCT   3007  /* change bandwidth statistics accounting */
 #define AID_NET_BT_STACK  3008  /* bluetooth: access config files */
 
+#define AID_EVERYBODY     9997  /* shared between all apps in the same profile */
 #define AID_MISC          9998  /* access to misc storage */
 #define AID_NOBODY        9999
 
@@ -153,6 +155,7 @@
     { "sdcard_av",     AID_SDCARD_AV, },
     { "sdcard_all",    AID_SDCARD_ALL, },
     { "logd",          AID_LOGD, },
+    { "shared_relro",  AID_SHARED_RELRO, },
 
     { "shell",         AID_SHELL, },
     { "cache",         AID_CACHE, },
@@ -167,6 +170,7 @@
     { "net_bw_acct",   AID_NET_BW_ACCT, },
     { "net_bt_stack",  AID_NET_BT_STACK, },
 
+    { "everybody",     AID_EVERYBODY, },
     { "misc",          AID_MISC, },
     { "nobody",        AID_NOBODY, },
 };
@@ -198,6 +202,7 @@
     { 00771, AID_SHELL,  AID_SHELL,  0, "data/local" },
     { 01771, AID_SYSTEM, AID_MISC,   0, "data/misc" },
     { 00770, AID_DHCP,   AID_DHCP,   0, "data/misc/dhcp" },
+    { 00771, AID_SHARED_RELRO, AID_SHARED_RELRO, 0, "data/misc/shared_relro" },
     { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media" },
     { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/Music" },
     { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data" },
diff --git a/include/system/audio.h b/include/system/audio.h
index 65479c3..cc4137e 100644
--- a/include/system/audio.h
+++ b/include/system/audio.h
@@ -61,8 +61,57 @@
 } audio_stream_type_t;
 
 /* Do not change these values without updating their counterparts
+ * in frameworks/base/media/java/android/media/AudioAttributes.java
+ */
+typedef enum {
+    AUDIO_CONTENT_TYPE_UNKNOWN      = 0,
+    AUDIO_CONTENT_TYPE_SPEECH       = 1,
+    AUDIO_CONTENT_TYPE_MUSIC        = 2,
+    AUDIO_CONTENT_TYPE_MOVIE        = 3,
+    AUDIO_CONTENT_TYPE_SONIFICATION = 4,
+
+    AUDIO_CONTENT_TYPE_CNT,
+    AUDIO_CONTENT_TYPE_MAX          = AUDIO_CONTENT_TYPE_CNT - 1,
+} audio_content_type_t;
+
+/* Do not change these values without updating their counterparts
+ * in frameworks/base/media/java/android/media/AudioAttributes.java
+ */
+typedef enum {
+    AUDIO_USAGE_UNKNOWN                            = 0,
+    AUDIO_USAGE_MEDIA                              = 1,
+    AUDIO_USAGE_VOICE_COMMUNICATION                = 2,
+    AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING     = 3,
+    AUDIO_USAGE_ALARM                              = 4,
+    AUDIO_USAGE_NOTIFICATION                       = 5,
+    AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE    = 6,
+    AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST = 7,
+    AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT = 8,
+    AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED = 9,
+    AUDIO_USAGE_NOTIFICATION_EVENT                 = 10,
+    AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY           = 11,
+    AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE     = 12,
+    AUDIO_USAGE_ASSISTANCE_SONIFICATION            = 13,
+    AUDIO_USAGE_GAME                               = 14,
+
+    AUDIO_USAGE_CNT,
+    AUDIO_USAGE_MAX                                = AUDIO_USAGE_CNT - 1,
+} audio_usage_t;
+
+typedef uint32_t audio_flags_mask_t;
+
+/* Do not change these values without updating their counterparts
+ * in frameworks/base/media/java/android/media/AudioAttributes.java
+ */
+enum {
+    AUDIO_FLAG_AUDIBILITY_ENFORCED = 0x1,
+    AUDIO_FLAG_SECURE              = 0x2,
+    AUDIO_FLAG_SCO                 = 0x4,
+};
+
+/* Do not change these values without updating their counterparts
  * in frameworks/base/media/java/android/media/MediaRecorder.java,
- * frameworks/av/services/audioflinger/AudioPolicyService.cpp,
+ * frameworks/av/services/audiopolicy/AudioPolicyService.cpp,
  * and system/media/audio_effects/include/audio_effects/audio_effects_conf.h!
  */
 typedef enum {
@@ -87,6 +136,16 @@
                                                 at the audio HAL. */
 } audio_source_t;
 
+/* Audio attributes */
+#define AUDIO_ATTRIBUTES_TAGS_MAX_SIZE 256
+typedef struct {
+    audio_content_type_t content_type;
+    audio_usage_t        usage;
+    audio_source_t       source;
+    audio_flags_mask_t   flags;
+    char                 tags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE]; /* UTF8 */
+} audio_attributes_t;
+
 /* special audio session values
  * (XXX: should this be living in the audio effects land?)
  */
@@ -437,6 +496,7 @@
     AUDIO_DEVICE_IN_LINE                  = AUDIO_DEVICE_BIT_IN | 0x8000,
     /* S/PDIF in */
     AUDIO_DEVICE_IN_SPDIF                 = AUDIO_DEVICE_BIT_IN | 0x10000,
+    AUDIO_DEVICE_IN_BLUETOOTH_A2DP        = AUDIO_DEVICE_BIT_IN | 0x20000,
     AUDIO_DEVICE_IN_DEFAULT               = AUDIO_DEVICE_BIT_IN | AUDIO_DEVICE_BIT_DEFAULT,
 
     AUDIO_DEVICE_IN_ALL     = (AUDIO_DEVICE_IN_COMMUNICATION |
@@ -456,6 +516,7 @@
                                AUDIO_DEVICE_IN_TV_TUNER |
                                AUDIO_DEVICE_IN_LINE |
                                AUDIO_DEVICE_IN_SPDIF |
+                               AUDIO_DEVICE_IN_BLUETOOTH_A2DP |
                                AUDIO_DEVICE_IN_DEFAULT),
     AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
     AUDIO_DEVICE_IN_ALL_USB  = (AUDIO_DEVICE_IN_USB_ACCESSORY |
@@ -527,6 +588,14 @@
 static const audio_offload_info_t AUDIO_INFO_INITIALIZER = {
     version: AUDIO_OFFLOAD_INFO_VERSION_CURRENT,
     size: sizeof(audio_offload_info_t),
+    sample_rate: 0,
+    channel_mask: 0,
+    format: AUDIO_FORMAT_DEFAULT,
+    stream_type: AUDIO_STREAM_VOICE_CALL,
+    bit_rate: 0,
+    duration_us: 0,
+    has_video: false,
+    is_streaming: false
 };
 
 
@@ -772,8 +841,17 @@
     return (device & AUDIO_DEVICE_BIT_IN) == 0;
 }
 
+static inline bool audio_is_a2dp_in_device(audio_devices_t device)
+{
+    if ((device & AUDIO_DEVICE_BIT_IN) != 0) {
+        device &= ~AUDIO_DEVICE_BIT_IN;
+        if ((popcount(device) == 1) && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP))
+            return true;
+    }
+    return false;
+}
 
-static inline bool audio_is_a2dp_device(audio_devices_t device)
+static inline bool audio_is_a2dp_out_device(audio_devices_t device)
 {
     if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_ALL_A2DP))
         return true;
@@ -781,6 +859,12 @@
         return false;
 }
 
+// Deprecated - use audio_is_a2dp_out_device() instead
+static inline bool audio_is_a2dp_device(audio_devices_t device)
+{
+    return audio_is_a2dp_out_device(device);
+}
+
 static inline bool audio_is_bluetooth_sco_device(audio_devices_t device)
 {
     if ((device & AUDIO_DEVICE_BIT_IN) == 0) {
diff --git a/include/system/sound_trigger.h b/include/system/sound_trigger.h
new file mode 100644
index 0000000..0270baa
--- /dev/null
+++ b/include/system/sound_trigger.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef ANDROID_SOUND_TRIGGER_H
+#define ANDROID_SOUND_TRIGGER_H
+
+#include <stdbool.h>
+
+#define SOUND_TRIGGER_MAX_STRING_LEN 64 /* max length of strings in properties or
+                                           descriptor structs */
+#define SOUND_TRIGGER_MAX_LOCALE_LEN 6  /* max length of locale string. e.g en_US */
+#define SOUND_TRIGGER_MAX_USERS 10      /* max number of concurrent users */
+#define SOUND_TRIGGER_MAX_PHRASES 10    /* max number of concurrent phrases */
+
+#define RECOGNITION_MODE_VOICE_TRIGGER 0x1       /* simple voice trigger */
+#define RECOGNITION_MODE_USER_IDENTIFICATION 0x2 /* trigger only if one user in model identified */
+#define RECOGNITION_MODE_USER_AUTHENTICATION 0x4 /* trigger only if one user in mode
+                                                    authenticated */
+
+#define RECOGNITION_STATUS_SUCCESS 0
+#define RECOGNITION_STATUS_ABORT 1
+#define RECOGNITION_STATUS_FAILURE 2
+
+
+typedef enum {
+    SOUND_MODEL_TYPE_UNKNOWN = -1,    /* use for unspecified sound model type */
+    SOUND_MODEL_TYPE_KEYPHRASE = 0    /* use for key phrase sound models */
+} sound_trigger_sound_model_type_t;
+
+
+typedef struct sound_trigger_uuid_s {
+    unsigned int   timeLow;
+    unsigned short timeMid;
+    unsigned short timeHiAndVersion;
+    unsigned short clockSeq;
+    unsigned char  node[6];
+} sound_trigger_uuid_t;
+
+/*
+ * sound trigger implementation descriptor read by the framework via get_properties().
+ * Used by SoundTrigger service to report to applications and manage concurrency and policy.
+ */
+struct sound_trigger_properties {
+    char                 implementor[SOUND_TRIGGER_MAX_STRING_LEN]; /* implementor name */
+    char                 description[SOUND_TRIGGER_MAX_STRING_LEN]; /* implementation description */
+    unsigned int         version;               /* implementation version */
+    sound_trigger_uuid_t uuid;                  /* unique implementation ID.
+                                                   Must change with version each version */
+    unsigned int         max_sound_models;      /* maximum number of concurrent sound models
+                                                   loaded */
+    unsigned int         max_key_phrases;       /* maximum number of key phrases */
+    unsigned int         max_users;             /* maximum number of concurrent users detected */
+    unsigned int         recognition_modes;     /* all supported modes.
+                                                   e.g RECOGNITION_MODE_VOICE_TRIGGER */
+    bool                 capture_transition;    /* supports seamless transition from detection
+                                                   to capture */
+    unsigned int         max_buffer_ms;         /* maximum buffering capacity in ms if
+                                                   capture_transition is true*/
+    bool                 concurrent_capture;    /* supports capture by other use cases while
+                                                   detection is active */
+    unsigned int         power_consumption_mw;  /* Rated power consumption when detection is active
+                                                   with TDB silence/sound/speech ratio */
+};
+
+typedef int sound_trigger_module_handle_t;
+
+struct sound_trigger_module_descriptor {
+    sound_trigger_module_handle_t   handle;
+    struct sound_trigger_properties properties;
+};
+
+typedef int sound_model_handle_t;
+
+/*
+ * Generic sound model descriptor. This struct is the header of a larger block passed to
+ * load_sound_model() and containing the binary data of the sound model.
+ * Proprietary representation of users in binary data must match information indicated
+ * by users field
+ */
+struct sound_trigger_sound_model {
+    sound_trigger_sound_model_type_t type;        /* model type. e.g. SOUND_MODEL_TYPE_KEYPHRASE */
+    unsigned int                     data_size;   /* size of opaque model data */
+    unsigned int                     data_offset; /* offset of opaque data start from head of struct
+                                                    (e.g sizeof struct sound_trigger_sound_model) */
+};
+
+/* key phrase descriptor */
+struct sound_trigger_phrase {
+    unsigned int recognition_mode;  /* recognition modes supported by this key phrase */
+    unsigned int num_users;         /* number of users in the key phrase */
+    char         locale[SOUND_TRIGGER_MAX_LOCALE_LEN]; /* locale - JAVA Locale style (e.g. en_US) */
+    char         text[SOUND_TRIGGER_MAX_STRING_LEN];   /* phrase text in UTF-8 format. */
+};
+
+/*
+ * Specialized sound model for key phrase detection.
+ * Proprietary representation of key phrases in binary data must match information indicated
+ * by phrases field
+ */
+struct sound_trigger_phrase_sound_model {
+    struct sound_trigger_sound_model common;
+    unsigned int                     num_phrases;   /* number of key phrases in model */
+    struct sound_trigger_phrase      phrases[SOUND_TRIGGER_MAX_PHRASES];
+};
+
+
+/*
+ * Generic recognition event sent via recognition callback
+ */
+struct sound_trigger_recognition_event {
+    int                              status;            /* recognition status e.g.
+                                                           RECOGNITION_STATUS_SUCCESS */
+    sound_trigger_sound_model_type_t type;              /* event type, same as sound model type.
+                                                           e.g. SOUND_MODEL_TYPE_KEYPHRASE */
+    sound_model_handle_t             model;             /* loaded sound model that triggered the
+                                                           event */
+    bool                             capture_available; /* it is possible to capture audio from this
+                                                           utterance buffered by the
+                                                           implementation */
+    int                              capture_session;   /* audio session ID. framework use */
+    int                              capture_delay_ms;  /* delay in ms between end of model
+                                                           detection and start of audio available
+                                                           for capture. A negative value is possible
+                                                           (e.g. if key phrase is also available for
+                                                           capture */
+    unsigned int                     data_size;         /* size of opaque event data */
+    unsigned int                     data_offset;       /* offset of opaque data start from start of
+                                                          this struct (e.g sizeof struct
+                                                          sound_trigger_phrase_recognition_event) */
+};
+
+/*
+ * Specialized recognition event for key phrase detection
+ */
+struct sound_trigger_phrase_recognition_extra {
+    unsigned int recognition_modes;
+    unsigned int num_users;
+    unsigned int confidence_levels[SOUND_TRIGGER_MAX_USERS];
+};
+
+struct sound_trigger_phrase_recognition_event {
+    struct sound_trigger_recognition_event common;
+    bool                                   key_phrase_in_capture; /* true if the key phrase is
+                                                                     present in audio data available
+                                                                     for capture after recognition
+                                                                     event is fired */
+    unsigned int                           num_phrases;
+    struct sound_trigger_phrase_recognition_extra phrase_extras[SOUND_TRIGGER_MAX_PHRASES];
+};
+
+
+#endif  // ANDROID_SOUND_TRIGGER_H
diff --git a/include/system/window.h b/include/system/window.h
index 588f9c6..16b7b67 100644
--- a/include/system/window.h
+++ b/include/system/window.h
@@ -26,6 +26,13 @@
 #include <system/graphics.h>
 #include <unistd.h>
 
+#ifndef __unused
+#define __unused __attribute__((__unused__))
+#endif
+#ifndef __deprecated
+#define __deprecated __attribute__((__deprecated__))
+#endif
+
 __BEGIN_DECLS
 
 /*****************************************************************************/
@@ -89,10 +96,10 @@
 
     // Implement the methods that sp<ANativeWindowBuffer> expects so that it
     // can be used to automatically refcount ANativeWindowBuffer's.
-    void incStrong(const void* id) const {
+    void incStrong(const void* /*id*/) const {
         common.incRef(const_cast<android_native_base_t*>(&common));
     }
-    void decStrong(const void* id) const {
+    void decStrong(const void* /*id*/) const {
         common.decRef(const_cast<android_native_base_t*>(&common));
     }
 #endif
@@ -352,10 +359,10 @@
 
     /* Implement the methods that sp<ANativeWindow> expects so that it
        can be used to automatically refcount ANativeWindow's. */
-    void incStrong(const void* id) const {
+    void incStrong(const void* /*id*/) const {
         common.incRef(const_cast<android_native_base_t*>(&common));
     }
-    void decStrong(const void* id) const {
+    void decStrong(const void* /*id*/) const {
         common.decRef(const_cast<android_native_base_t*>(&common));
     }
 #endif
@@ -582,7 +589,7 @@
   * android_native_window_t is deprecated.
   */
 typedef struct ANativeWindow ANativeWindow;
-typedef struct ANativeWindow android_native_window_t;
+typedef struct ANativeWindow android_native_window_t __deprecated;
 
 /*
  *  native_window_set_usage(..., usage)
@@ -603,13 +610,19 @@
 
 /* deprecated. Always returns 0. Don't call. */
 static inline int native_window_connect(
-        struct ANativeWindow* window, int api) {
+        struct ANativeWindow* window __unused, int api __unused) __deprecated;
+
+static inline int native_window_connect(
+        struct ANativeWindow* window __unused, int api __unused) {
     return 0;
 }
 
 /* deprecated. Always returns 0. Don't call. */
 static inline int native_window_disconnect(
-        struct ANativeWindow* window, int api) {
+        struct ANativeWindow* window __unused, int api __unused) __deprecated;
+
+static inline int native_window_disconnect(
+        struct ANativeWindow* window __unused, int api __unused) {
     return 0;
 }
 
@@ -664,6 +677,10 @@
  */
 static inline int native_window_set_active_rect(
         struct ANativeWindow* window,
+        android_native_rect_t const * active_rect) __deprecated;
+
+static inline int native_window_set_active_rect(
+        struct ANativeWindow* window,
         android_native_rect_t const * active_rect)
 {
     return native_window_set_post_transform_crop(window, active_rect);
@@ -691,6 +708,10 @@
  */
 static inline int native_window_set_buffers_geometry(
         struct ANativeWindow* window,
+        int w, int h, int format) __deprecated;
+
+static inline int native_window_set_buffers_geometry(
+        struct ANativeWindow* window,
         int w, int h, int format)
 {
     return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
diff --git a/include/utils/Functor.h b/include/utils/Functor.h
index e24ded4..09ea614 100644
--- a/include/utils/Functor.h
+++ b/include/utils/Functor.h
@@ -25,7 +25,7 @@
 public:
     Functor() {}
     virtual ~Functor() {}
-    virtual status_t operator ()(int what, void* data) { return NO_ERROR; }
+    virtual status_t operator ()(int /*what*/, void* /*data*/) { return NO_ERROR; }
 };
 
 }; // namespace android
diff --git a/include/utils/LruCache.h b/include/utils/LruCache.h
index f615a32..cd9d7f9 100644
--- a/include/utils/LruCache.h
+++ b/include/utils/LruCache.h
@@ -57,7 +57,7 @@
 
         bool next() {
             mIndex = mCache.mTable->next(mIndex);
-            return mIndex != -1;
+            return (ssize_t)mIndex != -1;
         }
 
         size_t index() const {
@@ -104,9 +104,13 @@
 
 // Implementation is here, because it's fully templated
 template <typename TKey, typename TValue>
-LruCache<TKey, TValue>::LruCache(uint32_t maxCapacity): mMaxCapacity(maxCapacity),
-    mNullValue(NULL), mTable(new BasicHashtable<TKey, Entry>), mYoungest(NULL), mOldest(NULL),
-    mListener(NULL) {
+LruCache<TKey, TValue>::LruCache(uint32_t maxCapacity)
+    : mTable(new BasicHashtable<TKey, Entry>)
+    , mListener(NULL)
+    , mOldest(NULL)
+    , mYoungest(NULL)
+    , mMaxCapacity(maxCapacity)
+    , mNullValue(NULL) {
 };
 
 template<typename K, typename V>
diff --git a/init/Android.mk b/init/Android.mk
index 15a23be..489dc93 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -25,7 +25,7 @@
 endif
 
 ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-LOCAL_CFLAGS += -DALLOW_LOCAL_PROP_OVERRIDE=1
+LOCAL_CFLAGS += -DALLOW_LOCAL_PROP_OVERRIDE=1 -DALLOW_DISABLE_SELINUX=1
 endif
 
 # Enable ueventd logging
diff --git a/init/devices.c b/init/devices.c
index 5d7ad3b..3119e8e 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -298,6 +298,37 @@
     }
 }
 
+/* Given a path that may start with a PCI device, populate the supplied buffer
+ * with the PCI domain/bus number and the peripheral ID and return 0.
+ * If it doesn't start with a PCI device, or there is some error, return -1 */
+static int find_pci_device_prefix(const char *path, char *buf, ssize_t buf_sz)
+{
+    const char *start, *end;
+
+    if (strncmp(path, "/devices/pci", 12))
+        return -1;
+
+    /* Beginning of the prefix is the initial "pci" after "/devices/" */
+    start = path + 9;
+
+    /* End of the prefix is two path '/' later, capturing the domain/bus number
+     * and the peripheral ID. Example: pci0000:00/0000:00:1f.2 */
+    end = strchr(start, '/');
+    if (!end)
+        return -1;
+    end = strchr(end + 1, '/');
+    if (!end)
+        return -1;
+
+    /* Make sure we have enough room for the string plus null terminator */
+    if (end - start + 1 > buf_sz)
+        return -1;
+
+    strncpy(buf, start, end - start);
+    buf[end - start] = '\0';
+    return 0;
+}
+
 #if LOG_UEVENTS
 
 static inline suseconds_t get_usecs(void)
@@ -422,11 +453,12 @@
     return NULL;
 }
 
-static char **parse_platform_block_device(struct uevent *uevent)
+static char **get_block_device_symlinks(struct uevent *uevent)
 {
     const char *device;
     struct platform_node *pdev;
     char *slash;
+    const char *type;
     int width;
     char buf[256];
     char link_path[256];
@@ -438,18 +470,24 @@
     struct stat info;
 
     pdev = find_platform_device(uevent->path);
-    if (!pdev)
+    if (pdev) {
+        device = pdev->name;
+        type = "platform";
+    } else if (!find_pci_device_prefix(uevent->path, buf, sizeof(buf))) {
+        device = buf;
+        type = "pci";
+    } else {
         return NULL;
-    device = pdev->name;
+    }
 
     char **links = malloc(sizeof(char *) * 4);
     if (!links)
         return NULL;
     memset(links, 0, sizeof(char *) * 4);
 
-    INFO("found platform device %s\n", device);
+    INFO("found %s device %s\n", type, device);
 
-    snprintf(link_path, sizeof(link_path), "/dev/block/platform/%s", device);
+    snprintf(link_path, sizeof(link_path), "/dev/block/%s/%s", type, device);
 
     if (uevent->partition_name) {
         p = strdup(uevent->partition_name);
@@ -556,7 +594,7 @@
     make_dir(base, 0755);
 
     if (!strncmp(uevent->path, "/devices/", 9))
-        links = parse_platform_block_device(uevent);
+        links = get_block_device_symlinks(uevent);
 
     handle_device(uevent->action, devpath, uevent->path, 1,
             uevent->major, uevent->minor, links);
diff --git a/init/init.c b/init/init.c
index 1538aa6..c79929b 100644
--- a/init/init.c
+++ b/init/init.c
@@ -841,24 +841,21 @@
 
 static const struct selinux_opt seopts_prop[] = {
         { SELABEL_OPT_PATH, "/property_contexts" },
+        { SELABEL_OPT_PATH, "/data/security/current/property_contexts" },
         { 0, NULL }
 };
 
 struct selabel_handle* selinux_android_prop_context_handle(void)
 {
-    int i = 0;
-    struct selabel_handle* sehandle = NULL;
-    while ((sehandle == NULL) && seopts_prop[i].value) {
-        sehandle = selabel_open(SELABEL_CTX_ANDROID_PROP, &seopts_prop[i], 1);
-        i++;
-    }
-
+    int policy_index = selinux_android_use_data_policy() ? 1 : 0;
+    struct selabel_handle* sehandle = selabel_open(SELABEL_CTX_ANDROID_PROP,
+                                                   &seopts_prop[policy_index], 1);
     if (!sehandle) {
         ERROR("SELinux:  Could not load property_contexts:  %s\n",
               strerror(errno));
         return NULL;
     }
-    INFO("SELinux: Loaded property contexts from %s\n", seopts_prop[i - 1].value);
+    INFO("SELinux: Loaded property contexts from %s\n", seopts_prop[policy_index].value);
     return sehandle;
 }
 
@@ -871,6 +868,7 @@
 
 static bool selinux_is_disabled(void)
 {
+#ifdef ALLOW_DISABLE_SELINUX
     char tmp[PROP_VALUE_MAX];
 
     if (access("/sys/fs/selinux", F_OK) != 0) {
@@ -884,12 +882,14 @@
         /* SELinux is compiled into the kernel, but we've been told to disable it. */
         return true;
     }
+#endif
 
     return false;
 }
 
 static bool selinux_is_enforcing(void)
 {
+#ifdef ALLOW_DISABLE_SELINUX
     char tmp[PROP_VALUE_MAX];
 
     if (property_get("ro.boot.selinux", tmp) == 0) {
@@ -906,6 +906,7 @@
         ERROR("SELinux: Unknown value of ro.boot.selinux. Got: \"%s\". Assuming enforcing.\n", tmp);
     }
 
+#endif
     return true;
 }
 
diff --git a/init/property_service.c b/init/property_service.c
index b25f998..97f281f 100644
--- a/init/property_service.c
+++ b/init/property_service.c
@@ -39,7 +39,6 @@
 #include <sys/types.h>
 #include <netinet/in.h>
 #include <sys/mman.h>
-#include <sys/atomics.h>
 #include <private/android_filesystem_config.h>
 
 #include <selinux/selinux.h>
diff --git a/libbacktrace/Android.build.mk b/libbacktrace/Android.build.mk
index dc73f9f..9882e31 100644
--- a/libbacktrace/Android.build.mk
+++ b/libbacktrace/Android.build.mk
@@ -72,6 +72,9 @@
 ifeq ($(build_type),host)
   # Only build if host builds are supported.
   ifeq ($(build_host),true)
+    ifneq ($($(module)_libc++),)
+      include external/libcxx/libcxx.mk
+    endif
     include $(BUILD_HOST_$(build_target))
   endif
 endif
diff --git a/libbacktrace/BacktraceThread.cpp b/libbacktrace/BacktraceThread.cpp
index 018d51f..b47cd2a 100644
--- a/libbacktrace/BacktraceThread.cpp
+++ b/libbacktrace/BacktraceThread.cpp
@@ -117,6 +117,12 @@
   futex(&futex_, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
 }
 
+void ThreadEntry::CopyUcontextFromSigcontext(void* sigcontext) {
+  ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(sigcontext);
+  // The only thing the unwinder cares about is the mcontext data.
+  memcpy(&ucontext_.uc_mcontext, &ucontext->uc_mcontext, sizeof(ucontext->uc_mcontext));
+}
+
 //-------------------------------------------------------------------------
 // BacktraceThread functions.
 //-------------------------------------------------------------------------
@@ -129,7 +135,7 @@
     return;
   }
 
-  entry->CopyUcontext(reinterpret_cast<ucontext_t*>(sigcontext));
+  entry->CopyUcontextFromSigcontext(sigcontext);
 
   // Indicate the ucontext is now valid.
   entry->Wake();
diff --git a/libbacktrace/BacktraceThread.h b/libbacktrace/BacktraceThread.h
index a75a807..ff3e9f3 100644
--- a/libbacktrace/BacktraceThread.h
+++ b/libbacktrace/BacktraceThread.h
@@ -40,14 +40,12 @@
 
   static void Remove(ThreadEntry* entry);
 
-  inline void CopyUcontext(ucontext_t* ucontext) {
-    memcpy(&ucontext_, ucontext, sizeof(ucontext_));
-  }
-
   void Wake();
 
   void Wait(int);
 
+  void CopyUcontextFromSigcontext(void*);
+
   inline void Lock() {
     pthread_mutex_lock(&mutex_);
     // Reset the futex value in case of multiple unwinds of the same thread.
diff --git a/libbacktrace/UnwindMap.cpp b/libbacktrace/UnwindMap.cpp
index 1615518..4f9831b 100644
--- a/libbacktrace/UnwindMap.cpp
+++ b/libbacktrace/UnwindMap.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <pthread.h>
+#include <stdlib.h>
 #include <sys/types.h>
 #include <unistd.h>
 
diff --git a/libctest/Android.mk b/libctest/Android.mk
deleted file mode 100644
index 815fabb..0000000
--- a/libctest/Android.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= libctest
-LOCAL_SRC_FILES := ctest.c
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libctest/NOTICE b/libctest/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/libctest/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, 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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/libctest/ctest.c b/libctest/ctest.c
deleted file mode 100644
index ee6331f..0000000
--- a/libctest/ctest.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2007 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 <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <ctest/ctest.h>
-
-#define MAX_TESTS 255
-
-/** Semi-random number used to identify assertion errors. */
-#define ASSERTION_ERROR 42
-    
-typedef void TestCase();
-
-/** A suite of tests. */
-typedef struct {
-    int size;
-    const char* testNames[MAX_TESTS];
-    TestCase* tests[MAX_TESTS];
-    int currentTest;
-    FILE* out;
-} TestSuite;
-
-/** Gets the test suite. Creates it if necessary. */
-static TestSuite* getTestSuite() {
-    static TestSuite* suite = NULL;
-    
-    if (suite != NULL) {
-        return suite;
-    }
-    
-    suite = calloc(1, sizeof(TestSuite));
-    assert(suite != NULL);
-    
-    suite->out = tmpfile();
-    assert(suite->out != NULL);
-    
-    return suite;
-}
-
-void addNamedTest(const char* name, TestCase* test) {
-    TestSuite* testSuite = getTestSuite();
-    assert(testSuite->size <= MAX_TESTS);
-    
-    int index = testSuite->size;
-    testSuite->testNames[index] = name;
-    testSuite->tests[index] = test;
-    
-    testSuite->size++;
-}
-
-/** Prints failures to stderr. */
-static void printFailures(int failures) {
-    TestSuite* suite = getTestSuite();
-
-    fprintf(stderr, "FAILURE! %d of %d tests failed. Failures:\n", 
-            failures, suite->size);
-
-    // Copy test output to stdout.
-    rewind(suite->out);
-    char buffer[512];
-    size_t read;
-    while ((read = fread(buffer, sizeof(char), 512, suite->out)) > 0) {
-        // TODO: Make sure we actually wrote 'read' bytes.
-        fwrite(buffer, sizeof(char), read, stderr);
-    }
-}
-
-/** Runs a single test case. */
-static int runCurrentTest() {
-    TestSuite* suite = getTestSuite();
-    
-    pid_t pid = fork();
-    if (pid == 0) {
-        // Child process. Runs test case.
-        suite->tests[suite->currentTest]();
-        
-        // Exit successfully.
-        exit(0);
-    } else if (pid < 0) {
-        fprintf(stderr, "Fork failed.");
-        exit(1); 
-    } else {
-        // Parent process. Wait for child.
-        int status;
-        waitpid(pid, &status, 0);
-        
-        if (!WIFEXITED(status)) {
-            return -1;
-        }
-        
-        return WEXITSTATUS(status);
-    }
-}
-
-void runTests() {
-    TestSuite* suite = getTestSuite();
-   
-    int failures = 0;
-    for (suite->currentTest = 0; suite->currentTest < suite->size; 
-            suite->currentTest++) {
-        // Flush stdout before forking.
-        fflush(stdout);
-        
-        int result = runCurrentTest();
-       
-        if (result != 0) {
-            printf("X");
-            
-            failures++;
-
-            // Handle errors other than assertions.
-            if (result != ASSERTION_ERROR) {
-                // TODO: Report file name.
-                fprintf(suite->out, "Process failed: [%s] status: %d\n",
-                        suite->testNames[suite->currentTest], result);
-                fflush(suite->out);
-            }
-        } else {
-            printf(".");
-        }
-    }
-
-    printf("\n");
-    
-    if (failures > 0) {
-        printFailures(failures);
-    } else {
-        printf("SUCCESS! %d tests ran successfully.\n", suite->size);
-    }
-}
-
-void assertTrueWithSource(int value, const char* file, int line, char* message) {
-    if (!value) {
-        TestSuite* suite = getTestSuite();
-
-        fprintf(suite->out, "Assertion failed: [%s:%d] %s: %s\n", file, line, 
-                suite->testNames[suite->currentTest], message);
-        fflush(suite->out);
-        
-        // Exit the process for this test case.
-        exit(ASSERTION_ERROR);
-    }
-}
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 20ad7ea..c0faed4 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -81,6 +81,8 @@
 ifneq ($(HOST_OS),windows)
 LOCAL_CFLAGS += -Werror
 endif
+LOCAL_MULTILIB := both
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 
@@ -94,6 +96,7 @@
 ifneq ($(HOST_OS),windows)
 LOCAL_CFLAGS += -Werror
 endif
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 # Tests for host
@@ -107,6 +110,7 @@
 LOCAL_SRC_FILES := str_parms.c hashmap.c memory.c
 LOCAL_STATIC_LIBRARIES := liblog
 LOCAL_MODULE_TAGS := optional
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_HOST_EXECUTABLE)
 
 
@@ -120,30 +124,36 @@
         ashmem-dev.c \
         debugger.c \
         klog.c \
+        memory.c \
         partition_utils.c \
         properties.c \
         qtaguid.c \
         trace.c \
-        uevent.c
+        uevent.c \
 
-ifeq ($(TARGET_ARCH),arm)
-    LOCAL_SRC_FILES += arch-arm/memset32.S
-else  # !arm
-    ifeq ($(TARGET_ARCH),x86)
-        LOCAL_CFLAGS += -DHAVE_MEMSET16 -DHAVE_MEMSET32
-        LOCAL_SRC_FILES += arch-x86/android_memset16.S arch-x86/android_memset32.S memory.c
-    else # !x86
-        ifeq ($(TARGET_ARCH),mips)
-            LOCAL_SRC_FILES += arch-mips/android_memset.c
-        else # !mips
-            LOCAL_SRC_FILES += memory.c
-        endif # !mips
-    endif # !x86
-endif # !arm
+LOCAL_SRC_FILES_arm += \
+        arch-arm/memset32.S \
+
+LOCAL_SRC_FILES_mips += \
+        arch-mips/android_memset.c \
+
+LOCAL_SRC_FILES_x86 += \
+        arch-x86/android_memset16.S \
+        arch-x86/android_memset32.S \
+
+LOCAL_SRC_FILES_x86_64 += \
+        arch-x86_64/android_memset16_SSE2-atom.S \
+        arch-x86_64/android_memset32_SSE2-atom.S \
+
+LOCAL_CFLAGS_arm += -DHAVE_MEMSET16 -DHAVE_MEMSET32
+LOCAL_CFLAGS_mips += -DHAVE_MEMSET16 -DHAVE_MEMSET32
+LOCAL_CFLAGS_x86 += -DHAVE_MEMSET16 -DHAVE_MEMSET32
+LOCAL_CFLAGS_x86_64 += -DHAVE_MEMSET16 -DHAVE_MEMSET32
 
 LOCAL_C_INCLUDES := $(libcutils_c_includes)
 LOCAL_STATIC_LIBRARIES := liblog
 LOCAL_CFLAGS += $(targetSmpFlag) -Werror
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -154,6 +164,7 @@
 LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_CFLAGS += $(targetSmpFlag) -Werror
 LOCAL_C_INCLUDES := $(libcutils_c_includes)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -162,6 +173,7 @@
 LOCAL_SRC_FILES := str_parms.c hashmap.c memory.c
 LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_MODULE_TAGS := optional
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_EXECUTABLE)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libcutils/android_reboot.c b/libcutils/android_reboot.c
index b7895fa..5d98295 100644
--- a/libcutils/android_reboot.c
+++ b/libcutils/android_reboot.c
@@ -57,7 +57,7 @@
         mount_dir[255] = 0;
         mount_type[255] = 0;
         mount_opts[255] = 0;
-        if ((match == 6) && !strncmp(mount_dev, "/dev/block", 10) && strstr(mount_opts, "rw")) {
+        if ((match == 6) && !strncmp(mount_dev, "/dev/block", 10) && strstr(mount_opts, "rw,")) {
             found_rw_fs = 1;
             break;
         }
diff --git a/libcutils/arch-x86_64/android_memset16_SSE2-atom.S b/libcutils/arch-x86_64/android_memset16_SSE2-atom.S
new file mode 100644
index 0000000..48a10ed
--- /dev/null
+++ b/libcutils/arch-x86_64/android_memset16_SSE2-atom.S
@@ -0,0 +1,564 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+/*
+ * Contributed by: Intel Corporation
+ */
+
+#include "cache.h"
+
+#ifndef L
+# define L(label)	.L##label
+#endif
+
+#ifndef ALIGN
+# define ALIGN(n)	.p2align n
+#endif
+
+#ifndef cfi_startproc
+# define cfi_startproc			.cfi_startproc
+#endif
+
+#ifndef cfi_endproc
+# define cfi_endproc			.cfi_endproc
+#endif
+
+#ifndef ENTRY
+# define ENTRY(name)			\
+	.type name,  @function; 	\
+	.globl name;			\
+	.p2align 4;			\
+name:					\
+	cfi_startproc
+#endif
+
+#ifndef END
+# define END(name)			\
+	cfi_endproc;			\
+	.size name, .-name
+#endif
+
+#define JMPTBL(I, B)	I - B
+
+/* Branch to an entry in a jump table.  TABLE is a jump table with
+   relative offsets.  INDEX is a register contains the index into the
+   jump table.  SCALE is the scale of INDEX.  */
+#define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \
+	lea    TABLE(%rip), %r11;						\
+	movslq (%r11, INDEX, SCALE), INDEX;				\
+	lea    (%r11, INDEX), INDEX;					\
+	jmp    *INDEX
+
+	.section .text.sse2,"ax",@progbits
+	ALIGN (4)
+ENTRY (android_memset16)	// Address in rdi
+	shr    $1, %rdx			// Count in rdx
+	movzwl %si, %ecx
+	/* Fill the whole ECX with pattern.  */
+	shl    $16, %esi
+	or     %esi, %ecx		// Pattern in ecx
+
+	cmp    $32, %rdx
+	jae    L(32wordsormore)
+
+L(write_less32words):
+	lea    (%rdi, %rdx, 2), %rdi
+	BRANCH_TO_JMPTBL_ENTRY (L(table_less32words), %rdx, 4)
+
+	.pushsection .rodata.sse2,"a",@progbits
+	ALIGN (2)
+L(table_less32words):
+	.int	JMPTBL (L(write_0words), L(table_less32words))
+	.int	JMPTBL (L(write_1words), L(table_less32words))
+	.int	JMPTBL (L(write_2words), L(table_less32words))
+	.int	JMPTBL (L(write_3words), L(table_less32words))
+	.int	JMPTBL (L(write_4words), L(table_less32words))
+	.int	JMPTBL (L(write_5words), L(table_less32words))
+	.int	JMPTBL (L(write_6words), L(table_less32words))
+	.int	JMPTBL (L(write_7words), L(table_less32words))
+	.int	JMPTBL (L(write_8words), L(table_less32words))
+	.int	JMPTBL (L(write_9words), L(table_less32words))
+	.int	JMPTBL (L(write_10words), L(table_less32words))
+	.int	JMPTBL (L(write_11words), L(table_less32words))
+	.int	JMPTBL (L(write_12words), L(table_less32words))
+	.int	JMPTBL (L(write_13words), L(table_less32words))
+	.int	JMPTBL (L(write_14words), L(table_less32words))
+	.int	JMPTBL (L(write_15words), L(table_less32words))
+	.int	JMPTBL (L(write_16words), L(table_less32words))
+	.int	JMPTBL (L(write_17words), L(table_less32words))
+	.int	JMPTBL (L(write_18words), L(table_less32words))
+	.int	JMPTBL (L(write_19words), L(table_less32words))
+	.int	JMPTBL (L(write_20words), L(table_less32words))
+	.int	JMPTBL (L(write_21words), L(table_less32words))
+	.int	JMPTBL (L(write_22words), L(table_less32words))
+	.int	JMPTBL (L(write_23words), L(table_less32words))
+	.int	JMPTBL (L(write_24words), L(table_less32words))
+	.int	JMPTBL (L(write_25words), L(table_less32words))
+	.int	JMPTBL (L(write_26words), L(table_less32words))
+	.int	JMPTBL (L(write_27words), L(table_less32words))
+	.int	JMPTBL (L(write_28words), L(table_less32words))
+	.int	JMPTBL (L(write_29words), L(table_less32words))
+	.int	JMPTBL (L(write_30words), L(table_less32words))
+	.int	JMPTBL (L(write_31words), L(table_less32words))
+	.popsection
+
+	ALIGN (4)
+L(write_28words):
+	movl   %ecx, -56(%rdi)
+	movl   %ecx, -52(%rdi)
+L(write_24words):
+	movl   %ecx, -48(%rdi)
+	movl   %ecx, -44(%rdi)
+L(write_20words):
+	movl   %ecx, -40(%rdi)
+	movl   %ecx, -36(%rdi)
+L(write_16words):
+	movl   %ecx, -32(%rdi)
+	movl   %ecx, -28(%rdi)
+L(write_12words):
+	movl   %ecx, -24(%rdi)
+	movl   %ecx, -20(%rdi)
+L(write_8words):
+	movl   %ecx, -16(%rdi)
+	movl   %ecx, -12(%rdi)
+L(write_4words):
+	movl   %ecx, -8(%rdi)
+	movl   %ecx, -4(%rdi)
+L(write_0words):
+	ret
+
+	ALIGN (4)
+L(write_29words):
+	movl   %ecx, -58(%rdi)
+	movl   %ecx, -54(%rdi)
+L(write_25words):
+	movl   %ecx, -50(%rdi)
+	movl   %ecx, -46(%rdi)
+L(write_21words):
+	movl   %ecx, -42(%rdi)
+	movl   %ecx, -38(%rdi)
+L(write_17words):
+	movl   %ecx, -34(%rdi)
+	movl   %ecx, -30(%rdi)
+L(write_13words):
+	movl   %ecx, -26(%rdi)
+	movl   %ecx, -22(%rdi)
+L(write_9words):
+	movl   %ecx, -18(%rdi)
+	movl   %ecx, -14(%rdi)
+L(write_5words):
+	movl   %ecx, -10(%rdi)
+	movl   %ecx, -6(%rdi)
+L(write_1words):
+	mov	%cx, -2(%rdi)
+	ret
+
+	ALIGN (4)
+L(write_30words):
+	movl   %ecx, -60(%rdi)
+	movl   %ecx, -56(%rdi)
+L(write_26words):
+	movl   %ecx, -52(%rdi)
+	movl   %ecx, -48(%rdi)
+L(write_22words):
+	movl   %ecx, -44(%rdi)
+	movl   %ecx, -40(%rdi)
+L(write_18words):
+	movl   %ecx, -36(%rdi)
+	movl   %ecx, -32(%rdi)
+L(write_14words):
+	movl   %ecx, -28(%rdi)
+	movl   %ecx, -24(%rdi)
+L(write_10words):
+	movl   %ecx, -20(%rdi)
+	movl   %ecx, -16(%rdi)
+L(write_6words):
+	movl   %ecx, -12(%rdi)
+	movl   %ecx, -8(%rdi)
+L(write_2words):
+	movl   %ecx, -4(%rdi)
+	ret
+
+	ALIGN (4)
+L(write_31words):
+	movl   %ecx, -62(%rdi)
+	movl   %ecx, -58(%rdi)
+L(write_27words):
+	movl   %ecx, -54(%rdi)
+	movl   %ecx, -50(%rdi)
+L(write_23words):
+	movl   %ecx, -46(%rdi)
+	movl   %ecx, -42(%rdi)
+L(write_19words):
+	movl   %ecx, -38(%rdi)
+	movl   %ecx, -34(%rdi)
+L(write_15words):
+	movl   %ecx, -30(%rdi)
+	movl   %ecx, -26(%rdi)
+L(write_11words):
+	movl   %ecx, -22(%rdi)
+	movl   %ecx, -18(%rdi)
+L(write_7words):
+	movl   %ecx, -14(%rdi)
+	movl   %ecx, -10(%rdi)
+L(write_3words):
+	movl   %ecx, -6(%rdi)
+	movw   %cx, -2(%rdi)
+	ret
+
+	ALIGN (4)
+L(32wordsormore):
+	shl    $1, %rdx
+	test   $0x01, %edi
+	jz     L(aligned2bytes)
+	mov    %ecx, (%rdi)
+	mov    %ecx, -4(%rdi, %rdx)
+	sub    $2, %rdx
+	add    $1, %rdi
+	rol    $8, %ecx
+L(aligned2bytes):
+	/* Fill xmm0 with the pattern.  */
+	movd   %ecx, %xmm0
+	pshufd $0, %xmm0, %xmm0
+
+	testl  $0xf, %edi
+	jz     L(aligned_16)
+/* RDX > 32 and RDI is not 16 byte aligned.  */
+	movdqu %xmm0, (%rdi)
+	mov    %rdi, %rsi
+	and    $-16, %rdi
+	add    $16, %rdi
+	sub    %rdi, %rsi
+	add    %rsi, %rdx
+
+	ALIGN (4)
+L(aligned_16):
+	cmp    $128, %rdx
+	jge    L(128bytesormore)
+
+L(aligned_16_less128bytes):
+	add    %rdx, %rdi
+	shr    $1, %rdx
+	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)
+
+	ALIGN (4)
+L(128bytesormore):
+	cmp    $SHARED_CACHE_SIZE, %rdx
+	jg     L(128bytesormore_nt)
+
+L(128bytesormore_normal):
+	sub    $128, %rdx
+	movdqa %xmm0, (%rdi)
+	movdqa %xmm0, 0x10(%rdi)
+	movdqa %xmm0, 0x20(%rdi)
+	movdqa %xmm0, 0x30(%rdi)
+	movdqa %xmm0, 0x40(%rdi)
+	movdqa %xmm0, 0x50(%rdi)
+	movdqa %xmm0, 0x60(%rdi)
+	movdqa %xmm0, 0x70(%rdi)
+	lea    128(%rdi), %rdi
+	cmp    $128, %rdx
+	jl     L(128bytesless_normal)
+
+	sub    $128, %rdx
+	movdqa %xmm0, (%rdi)
+	movdqa %xmm0, 0x10(%rdi)
+	movdqa %xmm0, 0x20(%rdi)
+	movdqa %xmm0, 0x30(%rdi)
+	movdqa %xmm0, 0x40(%rdi)
+	movdqa %xmm0, 0x50(%rdi)
+	movdqa %xmm0, 0x60(%rdi)
+	movdqa %xmm0, 0x70(%rdi)
+	lea    128(%rdi), %rdi
+	cmp    $128, %rdx
+	jl     L(128bytesless_normal)
+
+	sub    $128, %rdx
+	movdqa %xmm0, (%rdi)
+	movdqa %xmm0, 0x10(%rdi)
+	movdqa %xmm0, 0x20(%rdi)
+	movdqa %xmm0, 0x30(%rdi)
+	movdqa %xmm0, 0x40(%rdi)
+	movdqa %xmm0, 0x50(%rdi)
+	movdqa %xmm0, 0x60(%rdi)
+	movdqa %xmm0, 0x70(%rdi)
+	lea    128(%rdi), %rdi
+	cmp    $128, %rdx
+	jl     L(128bytesless_normal)
+
+	sub    $128, %rdx
+	movdqa %xmm0, (%rdi)
+	movdqa %xmm0, 0x10(%rdi)
+	movdqa %xmm0, 0x20(%rdi)
+	movdqa %xmm0, 0x30(%rdi)
+	movdqa %xmm0, 0x40(%rdi)
+	movdqa %xmm0, 0x50(%rdi)
+	movdqa %xmm0, 0x60(%rdi)
+	movdqa %xmm0, 0x70(%rdi)
+	lea    128(%rdi), %rdi
+	cmp    $128, %rdx
+	jge    L(128bytesormore_normal)
+
+L(128bytesless_normal):
+	add    %rdx, %rdi
+	shr    $1, %rdx
+	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)
+
+	ALIGN (4)
+L(128bytesormore_nt):
+	sub    $128, %rdx
+	movntdq %xmm0, (%rdi)
+	movntdq %xmm0, 0x10(%rdi)
+	movntdq %xmm0, 0x20(%rdi)
+	movntdq %xmm0, 0x30(%rdi)
+	movntdq %xmm0, 0x40(%rdi)
+	movntdq %xmm0, 0x50(%rdi)
+	movntdq %xmm0, 0x60(%rdi)
+	movntdq %xmm0, 0x70(%rdi)
+	lea    128(%rdi), %rdi
+	cmp    $128, %rdx
+	jge    L(128bytesormore_nt)
+
+	sfence
+	add    %rdx, %rdi
+	shr    $1, %rdx
+	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)
+
+	.pushsection .rodata.sse2,"a",@progbits
+	ALIGN (2)
+L(table_16_128bytes):
+	.int	JMPTBL (L(aligned_16_0bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_2bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_4bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_6bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_8bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_10bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_12bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_14bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_16bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_18bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_20bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_22bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_24bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_26bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_28bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_30bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_32bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_34bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_36bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_38bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_40bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_42bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_44bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_46bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_48bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_50bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_52bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_54bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_56bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_58bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_60bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_62bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_64bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_66bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_68bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_70bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_72bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_74bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_76bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_78bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_80bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_82bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_84bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_86bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_88bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_90bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_92bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_94bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_96bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_98bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_100bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_102bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_104bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_106bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_108bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_110bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_112bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_114bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_116bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_118bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_120bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_122bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_124bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_126bytes), L(table_16_128bytes))
+	.popsection
+
+	ALIGN (4)
+L(aligned_16_112bytes):
+	movdqa %xmm0, -112(%rdi)
+L(aligned_16_96bytes):
+	movdqa %xmm0, -96(%rdi)
+L(aligned_16_80bytes):
+	movdqa %xmm0, -80(%rdi)
+L(aligned_16_64bytes):
+	movdqa %xmm0, -64(%rdi)
+L(aligned_16_48bytes):
+	movdqa %xmm0, -48(%rdi)
+L(aligned_16_32bytes):
+	movdqa %xmm0, -32(%rdi)
+L(aligned_16_16bytes):
+	movdqa %xmm0, -16(%rdi)
+L(aligned_16_0bytes):
+	ret
+
+	ALIGN (4)
+L(aligned_16_114bytes):
+	movdqa %xmm0, -114(%rdi)
+L(aligned_16_98bytes):
+	movdqa %xmm0, -98(%rdi)
+L(aligned_16_82bytes):
+	movdqa %xmm0, -82(%rdi)
+L(aligned_16_66bytes):
+	movdqa %xmm0, -66(%rdi)
+L(aligned_16_50bytes):
+	movdqa %xmm0, -50(%rdi)
+L(aligned_16_34bytes):
+	movdqa %xmm0, -34(%rdi)
+L(aligned_16_18bytes):
+	movdqa %xmm0, -18(%rdi)
+L(aligned_16_2bytes):
+	movw   %cx, -2(%rdi)
+	ret
+
+	ALIGN (4)
+L(aligned_16_116bytes):
+	movdqa %xmm0, -116(%rdi)
+L(aligned_16_100bytes):
+	movdqa %xmm0, -100(%rdi)
+L(aligned_16_84bytes):
+	movdqa %xmm0, -84(%rdi)
+L(aligned_16_68bytes):
+	movdqa %xmm0, -68(%rdi)
+L(aligned_16_52bytes):
+	movdqa %xmm0, -52(%rdi)
+L(aligned_16_36bytes):
+	movdqa %xmm0, -36(%rdi)
+L(aligned_16_20bytes):
+	movdqa %xmm0, -20(%rdi)
+L(aligned_16_4bytes):
+	movl   %ecx, -4(%rdi)
+	ret
+
+	ALIGN (4)
+L(aligned_16_118bytes):
+	movdqa %xmm0, -118(%rdi)
+L(aligned_16_102bytes):
+	movdqa %xmm0, -102(%rdi)
+L(aligned_16_86bytes):
+	movdqa %xmm0, -86(%rdi)
+L(aligned_16_70bytes):
+	movdqa %xmm0, -70(%rdi)
+L(aligned_16_54bytes):
+	movdqa %xmm0, -54(%rdi)
+L(aligned_16_38bytes):
+	movdqa %xmm0, -38(%rdi)
+L(aligned_16_22bytes):
+	movdqa %xmm0, -22(%rdi)
+L(aligned_16_6bytes):
+	movl   %ecx, -6(%rdi)
+	movw   %cx, -2(%rdi)
+	ret
+
+	ALIGN (4)
+L(aligned_16_120bytes):
+	movdqa %xmm0, -120(%rdi)
+L(aligned_16_104bytes):
+	movdqa %xmm0, -104(%rdi)
+L(aligned_16_88bytes):
+	movdqa %xmm0, -88(%rdi)
+L(aligned_16_72bytes):
+	movdqa %xmm0, -72(%rdi)
+L(aligned_16_56bytes):
+	movdqa %xmm0, -56(%rdi)
+L(aligned_16_40bytes):
+	movdqa %xmm0, -40(%rdi)
+L(aligned_16_24bytes):
+	movdqa %xmm0, -24(%rdi)
+L(aligned_16_8bytes):
+	movq   %xmm0, -8(%rdi)
+	ret
+
+	ALIGN (4)
+L(aligned_16_122bytes):
+	movdqa %xmm0, -122(%rdi)
+L(aligned_16_106bytes):
+	movdqa %xmm0, -106(%rdi)
+L(aligned_16_90bytes):
+	movdqa %xmm0, -90(%rdi)
+L(aligned_16_74bytes):
+	movdqa %xmm0, -74(%rdi)
+L(aligned_16_58bytes):
+	movdqa %xmm0, -58(%rdi)
+L(aligned_16_42bytes):
+	movdqa %xmm0, -42(%rdi)
+L(aligned_16_26bytes):
+	movdqa %xmm0, -26(%rdi)
+L(aligned_16_10bytes):
+	movq   %xmm0, -10(%rdi)
+	movw   %cx, -2(%rdi)
+	ret
+
+	ALIGN (4)
+L(aligned_16_124bytes):
+	movdqa %xmm0, -124(%rdi)
+L(aligned_16_108bytes):
+	movdqa %xmm0, -108(%rdi)
+L(aligned_16_92bytes):
+	movdqa %xmm0, -92(%rdi)
+L(aligned_16_76bytes):
+	movdqa %xmm0, -76(%rdi)
+L(aligned_16_60bytes):
+	movdqa %xmm0, -60(%rdi)
+L(aligned_16_44bytes):
+	movdqa %xmm0, -44(%rdi)
+L(aligned_16_28bytes):
+	movdqa %xmm0, -28(%rdi)
+L(aligned_16_12bytes):
+	movq   %xmm0, -12(%rdi)
+	movl   %ecx, -4(%rdi)
+	ret
+
+	ALIGN (4)
+L(aligned_16_126bytes):
+	movdqa %xmm0, -126(%rdi)
+L(aligned_16_110bytes):
+	movdqa %xmm0, -110(%rdi)
+L(aligned_16_94bytes):
+	movdqa %xmm0, -94(%rdi)
+L(aligned_16_78bytes):
+	movdqa %xmm0, -78(%rdi)
+L(aligned_16_62bytes):
+	movdqa %xmm0, -62(%rdi)
+L(aligned_16_46bytes):
+	movdqa %xmm0, -46(%rdi)
+L(aligned_16_30bytes):
+	movdqa %xmm0, -30(%rdi)
+L(aligned_16_14bytes):
+	movq   %xmm0, -14(%rdi)
+	movl   %ecx, -6(%rdi)
+	movw   %cx, -2(%rdi)
+	ret
+
+END (android_memset16)
diff --git a/libcutils/arch-x86_64/android_memset32_SSE2-atom.S b/libcutils/arch-x86_64/android_memset32_SSE2-atom.S
new file mode 100644
index 0000000..4bdea8e
--- /dev/null
+++ b/libcutils/arch-x86_64/android_memset32_SSE2-atom.S
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+/*
+ * Contributed by: Intel Corporation
+ */
+
+#include "cache.h"
+
+#ifndef L
+# define L(label)	.L##label
+#endif
+
+#ifndef ALIGN
+# define ALIGN(n)	.p2align n
+#endif
+
+#ifndef cfi_startproc
+# define cfi_startproc			.cfi_startproc
+#endif
+
+#ifndef cfi_endproc
+# define cfi_endproc			.cfi_endproc
+#endif
+
+#ifndef ENTRY
+# define ENTRY(name)			\
+	.type name,  @function; 	\
+	.globl name;			\
+	.p2align 4;			\
+name:					\
+	cfi_startproc
+#endif
+
+#ifndef END
+# define END(name)			\
+	cfi_endproc;			\
+	.size name, .-name
+#endif
+
+#define JMPTBL(I, B)	I - B
+
+/* Branch to an entry in a jump table.  TABLE is a jump table with
+   relative offsets.  INDEX is a register contains the index into the
+   jump table.  SCALE is the scale of INDEX.  */
+#define BRANCH_TO_JMPTBL_ENTRY(TABLE, INDEX, SCALE) \
+	lea    TABLE(%rip), %r11;						\
+	movslq (%r11, INDEX, SCALE), INDEX;				\
+	lea    (%r11, INDEX), INDEX;					\
+	jmp    *INDEX
+
+	.section .text.sse2,"ax",@progbits
+	ALIGN (4)
+ENTRY (android_memset32)	// Address in rdi
+	shr    $2, %rdx			// Count in rdx
+	movl   %esi, %ecx		// Pattern in ecx
+
+	cmp    $16, %rdx
+	jae    L(16dbwordsormore)
+
+L(write_less16dbwords):
+	lea    (%rdi, %rdx, 4), %rdi
+	BRANCH_TO_JMPTBL_ENTRY (L(table_less16dbwords), %rdx, 4)
+
+	.pushsection .rodata.sse2,"a",@progbits
+	ALIGN (2)
+L(table_less16dbwords):
+	.int	JMPTBL (L(write_0dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_1dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_2dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_3dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_4dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_5dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_6dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_7dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_8dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_9dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_10dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_11dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_12dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_13dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_14dbwords), L(table_less16dbwords))
+	.int	JMPTBL (L(write_15dbwords), L(table_less16dbwords))
+	.popsection
+
+	ALIGN (4)
+L(write_15dbwords):
+	movl   %ecx, -60(%rdi)
+L(write_14dbwords):
+	movl   %ecx, -56(%rdi)
+L(write_13dbwords):
+	movl   %ecx, -52(%rdi)
+L(write_12dbwords):
+	movl   %ecx, -48(%rdi)
+L(write_11dbwords):
+	movl   %ecx, -44(%rdi)
+L(write_10dbwords):
+	movl   %ecx, -40(%rdi)
+L(write_9dbwords):
+	movl   %ecx, -36(%rdi)
+L(write_8dbwords):
+	movl   %ecx, -32(%rdi)
+L(write_7dbwords):
+	movl   %ecx, -28(%rdi)
+L(write_6dbwords):
+	movl   %ecx, -24(%rdi)
+L(write_5dbwords):
+	movl   %ecx, -20(%rdi)
+L(write_4dbwords):
+	movl   %ecx, -16(%rdi)
+L(write_3dbwords):
+	movl   %ecx, -12(%rdi)
+L(write_2dbwords):
+	movl   %ecx, -8(%rdi)
+L(write_1dbwords):
+	movl   %ecx, -4(%rdi)
+L(write_0dbwords):
+	ret
+
+	ALIGN (4)
+L(16dbwordsormore):
+	test   $3, %edi
+	jz     L(aligned4bytes)
+	mov    %ecx, (%rdi)
+	mov    %ecx, -4(%rdi, %rdx, 4)
+	sub    $1, %rdx
+	rol    $24, %ecx
+	add    $1, %rdi
+	test   $3, %edi
+	jz     L(aligned4bytes)
+	ror    $8, %ecx
+	add    $1, %rdi
+	test   $3, %edi
+	jz     L(aligned4bytes)
+	ror    $8, %ecx
+	add    $1, %rdi
+L(aligned4bytes):
+	shl    $2, %rdx
+
+	/* Fill xmm0 with the pattern.  */
+	movd   %ecx, %xmm0
+	pshufd $0, %xmm0, %xmm0
+
+	testl  $0xf, %edi
+	jz     L(aligned_16)
+/* RDX > 32 and RDI is not 16 byte aligned.  */
+	movdqu %xmm0, (%rdi)
+	mov    %rdi, %rsi
+	and    $-16, %rdi
+	add    $16, %rdi
+	sub    %rdi, %rsi
+	add    %rsi, %rdx
+
+	ALIGN (4)
+L(aligned_16):
+	cmp    $128, %rdx
+	jge    L(128bytesormore)
+
+L(aligned_16_less128bytes):
+	add    %rdx, %rdi
+	shr    $2, %rdx
+	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)
+
+	ALIGN (4)
+L(128bytesormore):
+	cmp    $SHARED_CACHE_SIZE, %rdx
+	jg     L(128bytesormore_nt)
+
+L(128bytesormore_normal):
+	sub    $128, %rdx
+	movdqa %xmm0, (%rdi)
+	movdqa %xmm0, 0x10(%rdi)
+	movdqa %xmm0, 0x20(%rdi)
+	movdqa %xmm0, 0x30(%rdi)
+	movdqa %xmm0, 0x40(%rdi)
+	movdqa %xmm0, 0x50(%rdi)
+	movdqa %xmm0, 0x60(%rdi)
+	movdqa %xmm0, 0x70(%rdi)
+	lea    128(%rdi), %rdi
+	cmp    $128, %rdx
+	jl     L(128bytesless_normal)
+
+	sub    $128, %rdx
+	movdqa %xmm0, (%rdi)
+	movdqa %xmm0, 0x10(%rdi)
+	movdqa %xmm0, 0x20(%rdi)
+	movdqa %xmm0, 0x30(%rdi)
+	movdqa %xmm0, 0x40(%rdi)
+	movdqa %xmm0, 0x50(%rdi)
+	movdqa %xmm0, 0x60(%rdi)
+	movdqa %xmm0, 0x70(%rdi)
+	lea    128(%rdi), %rdi
+	cmp    $128, %rdx
+	jl     L(128bytesless_normal)
+
+	sub    $128, %rdx
+	movdqa %xmm0, (%rdi)
+	movdqa %xmm0, 0x10(%rdi)
+	movdqa %xmm0, 0x20(%rdi)
+	movdqa %xmm0, 0x30(%rdi)
+	movdqa %xmm0, 0x40(%rdi)
+	movdqa %xmm0, 0x50(%rdi)
+	movdqa %xmm0, 0x60(%rdi)
+	movdqa %xmm0, 0x70(%rdi)
+	lea    128(%rdi), %rdi
+	cmp    $128, %rdx
+	jl     L(128bytesless_normal)
+
+	sub    $128, %rdx
+	movdqa %xmm0, (%rdi)
+	movdqa %xmm0, 0x10(%rdi)
+	movdqa %xmm0, 0x20(%rdi)
+	movdqa %xmm0, 0x30(%rdi)
+	movdqa %xmm0, 0x40(%rdi)
+	movdqa %xmm0, 0x50(%rdi)
+	movdqa %xmm0, 0x60(%rdi)
+	movdqa %xmm0, 0x70(%rdi)
+	lea    128(%rdi), %rdi
+	cmp    $128, %rdx
+	jge    L(128bytesormore_normal)
+
+L(128bytesless_normal):
+	add    %rdx, %rdi
+	shr    $2, %rdx
+	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)
+
+	ALIGN (4)
+L(128bytesormore_nt):
+	sub    $128, %rdx
+	movntdq %xmm0, (%rdi)
+	movntdq %xmm0, 0x10(%rdi)
+	movntdq %xmm0, 0x20(%rdi)
+	movntdq %xmm0, 0x30(%rdi)
+	movntdq %xmm0, 0x40(%rdi)
+	movntdq %xmm0, 0x50(%rdi)
+	movntdq %xmm0, 0x60(%rdi)
+	movntdq %xmm0, 0x70(%rdi)
+	lea    128(%rdi), %rdi
+	cmp    $128, %rdx
+	jge    L(128bytesormore_nt)
+
+	sfence
+	add    %rdx, %rdi
+	shr    $2, %rdx
+	BRANCH_TO_JMPTBL_ENTRY (L(table_16_128bytes), %rdx, 4)
+
+	.pushsection .rodata.sse2,"a",@progbits
+	ALIGN (2)
+L(table_16_128bytes):
+	.int	JMPTBL (L(aligned_16_0bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_4bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_8bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_12bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_16bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_20bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_24bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_28bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_32bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_36bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_40bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_44bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_48bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_52bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_56bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_60bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_64bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_68bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_72bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_76bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_80bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_84bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_88bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_92bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_96bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_100bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_104bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_108bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_112bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_116bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_120bytes), L(table_16_128bytes))
+	.int	JMPTBL (L(aligned_16_124bytes), L(table_16_128bytes))
+	.popsection
+
+	ALIGN (4)
+L(aligned_16_112bytes):
+	movdqa	%xmm0, -112(%rdi)
+L(aligned_16_96bytes):
+	movdqa	%xmm0, -96(%rdi)
+L(aligned_16_80bytes):
+	movdqa	%xmm0, -80(%rdi)
+L(aligned_16_64bytes):
+	movdqa	%xmm0, -64(%rdi)
+L(aligned_16_48bytes):
+	movdqa	%xmm0, -48(%rdi)
+L(aligned_16_32bytes):
+	movdqa	%xmm0, -32(%rdi)
+L(aligned_16_16bytes):
+	movdqa	%xmm0, -16(%rdi)
+L(aligned_16_0bytes):
+	ret
+
+	ALIGN (4)
+L(aligned_16_116bytes):
+	movdqa	%xmm0, -116(%rdi)
+L(aligned_16_100bytes):
+	movdqa	%xmm0, -100(%rdi)
+L(aligned_16_84bytes):
+	movdqa	%xmm0, -84(%rdi)
+L(aligned_16_68bytes):
+	movdqa	%xmm0, -68(%rdi)
+L(aligned_16_52bytes):
+	movdqa	%xmm0, -52(%rdi)
+L(aligned_16_36bytes):
+	movdqa	%xmm0, -36(%rdi)
+L(aligned_16_20bytes):
+	movdqa	%xmm0, -20(%rdi)
+L(aligned_16_4bytes):
+	movl	%ecx, -4(%rdi)
+	ret
+
+	ALIGN (4)
+L(aligned_16_120bytes):
+	movdqa	%xmm0, -120(%rdi)
+L(aligned_16_104bytes):
+	movdqa	%xmm0, -104(%rdi)
+L(aligned_16_88bytes):
+	movdqa	%xmm0, -88(%rdi)
+L(aligned_16_72bytes):
+	movdqa	%xmm0, -72(%rdi)
+L(aligned_16_56bytes):
+	movdqa	%xmm0, -56(%rdi)
+L(aligned_16_40bytes):
+	movdqa	%xmm0, -40(%rdi)
+L(aligned_16_24bytes):
+	movdqa	%xmm0, -24(%rdi)
+L(aligned_16_8bytes):
+	movq	%xmm0, -8(%rdi)
+	ret
+
+	ALIGN (4)
+L(aligned_16_124bytes):
+	movdqa	%xmm0, -124(%rdi)
+L(aligned_16_108bytes):
+	movdqa	%xmm0, -108(%rdi)
+L(aligned_16_92bytes):
+	movdqa	%xmm0, -92(%rdi)
+L(aligned_16_76bytes):
+	movdqa	%xmm0, -76(%rdi)
+L(aligned_16_60bytes):
+	movdqa	%xmm0, -60(%rdi)
+L(aligned_16_44bytes):
+	movdqa	%xmm0, -44(%rdi)
+L(aligned_16_28bytes):
+	movdqa	%xmm0, -28(%rdi)
+L(aligned_16_12bytes):
+	movq	%xmm0, -12(%rdi)
+	movl	%ecx, -4(%rdi)
+	ret
+
+END (android_memset32)
diff --git a/libcutils/arch-x86_64/cache.h b/libcutils/arch-x86_64/cache.h
new file mode 100644
index 0000000..ab5dd2f
--- /dev/null
+++ b/libcutils/arch-x86_64/cache.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+/*
+ * Contributed by: Intel Corporation
+ */
+
+#if defined(__slm__)
+/* Values are optimized for Silvermont */
+#define SHARED_CACHE_SIZE	(1024*1024)			/* Silvermont L2 Cache */
+#define DATA_CACHE_SIZE		(24*1024)			/* Silvermont L1 Data Cache */
+#else
+/* Values are optimized for Atom */
+#define SHARED_CACHE_SIZE	(512*1024)			/* Atom L2 Cache */
+#define DATA_CACHE_SIZE		(24*1024)			/* Atom L1 Data Cache */
+#endif
+
+#define SHARED_CACHE_SIZE_HALF	(SHARED_CACHE_SIZE / 2)
+#define DATA_CACHE_SIZE_HALF	(DATA_CACHE_SIZE / 2)
diff --git a/libcutils/dlmalloc_stubs.c b/libcutils/dlmalloc_stubs.c
index 6dca911..2db473d 100644
--- a/libcutils/dlmalloc_stubs.c
+++ b/libcutils/dlmalloc_stubs.c
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include "../../../bionic/libc/bionic/dlmalloc.h"
 #include "log/log.h"
 
 #define UNUSED __attribute__((__unused__))
diff --git a/libion/Android.mk b/libion/Android.mk
index e5d495b..6562cd3 100644
--- a/libion/Android.mk
+++ b/libion/Android.mk
@@ -1,4 +1,4 @@
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := ion.c
@@ -7,6 +7,7 @@
 LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/kernel-headers
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include $(LOCAL_PATH)/kernel-headers
+LOCAL_CFLAGS := -Werror
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -15,6 +16,7 @@
 LOCAL_MODULE_TAGS := optional tests
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/kernel-headers
 LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_CFLAGS := -Werror
 include $(BUILD_EXECUTABLE)
 
 include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/liblog/Android.mk b/liblog/Android.mk
index 69ca416..a7eead9 100644
--- a/liblog/Android.mk
+++ b/liblog/Android.mk
@@ -58,6 +58,7 @@
 LOCAL_MODULE := liblog
 LOCAL_SRC_FILES := $(liblog_host_sources)
 LOCAL_CFLAGS := -DFAKE_LOG_DEVICE=1 -Werror
+LOCAL_MULTILIB := both
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -66,6 +67,7 @@
 ifeq ($(strip $(HOST_OS)),linux)
 LOCAL_LDLIBS := -lrt
 endif
+LOCAL_MULTILIB := both
 include $(BUILD_HOST_SHARED_LIBRARY)
 
 
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index 121d84d..f10eb8e 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -159,10 +159,14 @@
     struct timespec ts;
     log_time realtime_ts;
     size_t i, payload_size;
+    static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */
 
-    if (getuid() == AID_LOGD) {
+    if (last_uid == AID_ROOT) { /* have we called to get the UID yet? */
+        last_uid = getuid();
+    }
+    if (last_uid == AID_LOGD) { /* logd, after initialization and priv drop */
         /*
-         * ignore log messages we send to ourself.
+         * ignore log messages we send to ourself (logd).
          * Such log messages are often generated by libraries we depend on
          * which use standard Android logging.
          */
@@ -193,6 +197,10 @@
      *  };
      */
 
+    clock_gettime(CLOCK_REALTIME, &ts);
+    realtime_ts.tv_sec = ts.tv_sec;
+    realtime_ts.tv_nsec = ts.tv_nsec;
+
     log_id_buf = log_id;
     tid = gettid();
 
@@ -200,11 +208,6 @@
     newVec[0].iov_len    = sizeof_log_id_t;
     newVec[1].iov_base   = (unsigned char *) &tid;
     newVec[1].iov_len    = sizeof(tid);
-
-    clock_gettime(CLOCK_REALTIME, &ts);
-    realtime_ts.tv_sec = ts.tv_sec;
-    realtime_ts.tv_nsec = ts.tv_nsec;
-
     newVec[2].iov_base   = (unsigned char *) &realtime_ts;
     newVec[2].iov_len    = sizeof(log_time);
 
diff --git a/liblog/tests/libc_test.cpp b/liblog/tests/libc_test.cpp
index 0abc375..9839729 100644
--- a/liblog/tests/libc_test.cpp
+++ b/liblog/tests/libc_test.cpp
@@ -99,7 +99,7 @@
     pid_t pid = getpid();
 
     ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
-        (log_id_t)LOG_ID_MAIN, O_RDONLY | O_NDELAY, 1000, pid)));
+        (log_id_t)LOG_ID_CRASH, O_RDONLY | O_NDELAY, 1000, pid)));
 
     char b[80];
     struct timespec ts;
@@ -119,7 +119,7 @@
 
         ASSERT_EQ(log_msg.entry.pid, pid);
 
-        if ((int)log_msg.id() != LOG_ID_MAIN) {
+        if ((int)log_msg.id() != LOG_ID_CRASH) {
             continue;
         }
 
diff --git a/libnetutils/Android.mk b/libnetutils/Android.mk
index aba4621..1f61511 100644
--- a/libnetutils/Android.mk
+++ b/libnetutils/Android.mk
@@ -1,7 +1,7 @@
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
+LOCAL_SRC_FILES := \
         dhcpclient.c \
         dhcpmsg.c \
         dhcp_utils.c \
@@ -12,6 +12,8 @@
         libcutils \
         liblog
 
-LOCAL_MODULE:= libnetutils
+LOCAL_MODULE := libnetutils
+
+LOCAL_CFLAGS := -Werror
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libnetutils/dhcpclient.c b/libnetutils/dhcpclient.c
index 34500e7..b58120e 100644
--- a/libnetutils/dhcpclient.c
+++ b/libnetutils/dhcpclient.c
@@ -282,16 +282,18 @@
     ALOGD("chaddr = {%s}", buf);
 
     for (n = 0; n < 64; n++) {
-        if ((msg->sname[n] < ' ') || (msg->sname[n] > 127)) {
-            if (msg->sname[n] == 0) break;
+        unsigned char x = msg->sname[n];
+        if ((x < ' ') || (x > 127)) {
+            if (x == 0) break;
             msg->sname[n] = '.';
         }
     }
     msg->sname[63] = 0;
 
     for (n = 0; n < 128; n++) {
-        if ((msg->file[n] < ' ') || (msg->file[n] > 127)) {
-            if (msg->file[n] == 0) break;
+        unsigned char x = msg->file[n];
+        if ((x < ' ') || (x > 127)) {
+            if (x == 0) break;
             msg->file[n] = '.';
         }
     }
diff --git a/libpixelflinger/codeflinger/CodeCache.cpp b/libpixelflinger/codeflinger/CodeCache.cpp
index 7446da2..8afe0a9 100644
--- a/libpixelflinger/codeflinger/CodeCache.cpp
+++ b/libpixelflinger/codeflinger/CodeCache.cpp
@@ -89,7 +89,7 @@
         gExecutableStore = mmap(NULL, kMaxCodeCacheCapacity,
                                 PROT_READ | PROT_WRITE | PROT_EXEC,
                                 MAP_PRIVATE, fd, 0);
-        LOG_ALWAYS_FATAL_IF(gExecutableStore == NULL,
+        LOG_ALWAYS_FATAL_IF(gExecutableStore == MAP_FAILED,
                             "Creating code cache, mmap failed with error "
                             "'%s'", strerror(errno));
         close(fd);
diff --git a/libpixelflinger/scanline.cpp b/libpixelflinger/scanline.cpp
index f84a28a..26b9a3e 100644
--- a/libpixelflinger/scanline.cpp
+++ b/libpixelflinger/scanline.cpp
@@ -39,7 +39,7 @@
 #include "codeflinger/ARMAssembler.h"
 #elif defined(__aarch64__)
 #include "codeflinger/Arm64Assembler.h"
-#elif defined(__mips__)
+#elif defined(__mips__) && !defined(__LP64__)
 #include "codeflinger/MIPSAssembler.h"
 #endif
 //#include "codeflinger/ARMAssemblerOptimizer.h"
@@ -59,7 +59,7 @@
 #   define ANDROID_CODEGEN      ANDROID_CODEGEN_GENERATED
 #endif
 
-#if defined(__arm__) || defined(__mips__) || defined(__aarch64__)
+#if defined(__arm__) || (defined(__mips__) && !defined(__LP64__)) || defined(__aarch64__)
 #   define ANDROID_ARM_CODEGEN  1
 #else
 #   define ANDROID_ARM_CODEGEN  0
@@ -73,7 +73,7 @@
  */
 #define DEBUG_NEEDS  0
 
-#ifdef __mips__
+#if defined( __mips__) && !defined(__LP64__)
 #define ASSEMBLY_SCRATCH_SIZE   4096
 #elif defined(__aarch64__)
 #define ASSEMBLY_SCRATCH_SIZE   8192
@@ -134,7 +134,7 @@
 #elif defined(__aarch64__)
 extern "C" void scanline_t32cb16blend_arm64(uint16_t*, uint32_t*, size_t);
 extern "C" void scanline_col32cb16blend_arm64(uint16_t *dst, uint32_t col, size_t ct);
-#elif defined(__mips__)
+#elif defined(__mips__)  && !defined(__LP64__)
 extern "C" void scanline_t32cb16blend_mips(uint16_t*, uint32_t*, size_t);
 #endif
 
@@ -2175,7 +2175,7 @@
 
 void scanline_t32cb16blend(context_t* c)
 {
-#if ((ANDROID_CODEGEN >= ANDROID_CODEGEN_ASM) && (defined(__arm__) || defined(__mips__) || defined(__aarch64__)))
+#if ((ANDROID_CODEGEN >= ANDROID_CODEGEN_ASM) && (defined(__arm__) || (defined(__mips__) && !defined(__LP64__)) || defined(__aarch64__)))
     int32_t x = c->iterators.xl;
     size_t ct = c->iterators.xr - x;
     int32_t y = c->iterators.y;
diff --git a/libpixelflinger/tests/codegen/codegen.cpp b/libpixelflinger/tests/codegen/codegen.cpp
index e9f6c61..46c1ccc 100644
--- a/libpixelflinger/tests/codegen/codegen.cpp
+++ b/libpixelflinger/tests/codegen/codegen.cpp
@@ -52,7 +52,7 @@
     GGLAssembler assembler( new ARMAssembler(a) );
 #endif
 
-#if defined(__mips__)
+#if defined(__mips__) && !defined(__LP64__)
     GGLAssembler assembler( new ArmToMipsAssembler(a) );
 #endif
 
diff --git a/libsuspend/Android.mk b/libsuspend/Android.mk
index a2fa3e0..1ba2f59 100644
--- a/libsuspend/Android.mk
+++ b/libsuspend/Android.mk
@@ -18,6 +18,7 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
 LOCAL_SHARED_LIBRARIES := $(libsuspend_libraries)
+LOCAL_CFLAGS := -Werror
 #LOCAL_CFLAGS += -DLOG_NDEBUG=0
 include $(BUILD_SHARED_LIBRARY)
 
@@ -27,5 +28,6 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
+LOCAL_CFLAGS := -Werror
 #LOCAL_CFLAGS += -DLOG_NDEBUG=0
 include $(BUILD_STATIC_LIBRARY)
diff --git a/libsync/Android.mk b/libsync/Android.mk
index 626b762..fd1c88c 100644
--- a/libsync/Android.mk
+++ b/libsync/Android.mk
@@ -7,6 +7,7 @@
 LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_CFLAGS := -Werror
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -15,4 +16,5 @@
 LOCAL_MODULE_TAGS := optional tests
 LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_CFLAGS := -Werror
 include $(BUILD_EXECUTABLE)
diff --git a/libusbhost/Android.mk b/libusbhost/Android.mk
index acfc020..5c12f2c 100644
--- a/libusbhost/Android.mk
+++ b/libusbhost/Android.mk
@@ -25,6 +25,7 @@
 
 LOCAL_MODULE := libusbhost
 LOCAL_SRC_FILES := usbhost.c
+LOCAL_CFLAGS := -Werror
 
 include $(BUILD_HOST_STATIC_LIBRARY)
 
@@ -38,7 +39,7 @@
 LOCAL_MODULE := libusbhost
 LOCAL_SRC_FILES := usbhost.c
 
-LOCAL_CFLAGS := -g -DUSE_LIBLOG
+LOCAL_CFLAGS := -g -DUSE_LIBLOG -Werror
 
 # needed for logcat
 LOCAL_SHARED_LIBRARIES := libcutils
@@ -52,5 +53,6 @@
 
 LOCAL_MODULE := libusbhost
 LOCAL_SRC_FILES := usbhost.c
+LOCAL_CFLAGS := -Werror
 
 include $(BUILD_STATIC_LIBRARY)
diff --git a/libutils/Android.mk b/libutils/Android.mk
index 1fef049..9343f8e 100644
--- a/libutils/Android.mk
+++ b/libutils/Android.mk
@@ -44,7 +44,7 @@
 	VectorImpl.cpp \
 	misc.cpp
 
-host_commonCflags := -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS)
+host_commonCflags := -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS) -Werror
 
 ifeq ($(HOST_OS),windows)
 ifeq ($(strip $(USE_CYGWIN),),)
@@ -70,6 +70,7 @@
 LOCAL_MODULE:= libutils
 LOCAL_STATIC_LIBRARIES := liblog
 LOCAL_CFLAGS += $(host_commonCflags)
+LOCAL_MULTILIB := both
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 
@@ -100,6 +101,7 @@
 ifeq ($(TARGET_ARCH),mips)
 LOCAL_CFLAGS += -DALIGN_DOUBLE
 endif
+LOCAL_CFLAGS += -Werror
 
 LOCAL_C_INCLUDES += \
 		bionic/libc/private \
@@ -127,7 +129,8 @@
         libbacktrace \
         libcutils \
         libdl \
-        liblog \
+        liblog
+LOCAL_CFLAGS := -Werror
 
 include external/stlport/libstlport.mk
 
diff --git a/libutils/BlobCache.cpp b/libutils/BlobCache.cpp
index 660917b..f00bf14 100644
--- a/libutils/BlobCache.cpp
+++ b/libutils/BlobCache.cpp
@@ -28,7 +28,7 @@
 namespace android {
 
 // BlobCache::Header::mMagicNumber value
-static const uint32_t blobCacheMagic = '_Bb$';
+static const uint32_t blobCacheMagic = ('_' << 24) + ('B' << 16) + ('b' << 8) + '$';
 
 // BlobCache::Header::mBlobCacheVersion value
 static const uint32_t blobCacheVersion = 1;
@@ -49,7 +49,7 @@
     mRandState[1] = (now >> 16) & 0xFFFF;
     mRandState[2] = (now >> 32) & 0xFFFF;
 #endif
-    ALOGV("initializing random seed using %lld", now);
+    ALOGV("initializing random seed using %lld", (unsigned long long)now);
 }
 
 void BlobCache::set(const void* key, size_t keySize, const void* value,
diff --git a/libutils/FileMap.cpp b/libutils/FileMap.cpp
index 933e7aa..be4b14f 100644
--- a/libutils/FileMap.cpp
+++ b/libutils/FileMap.cpp
@@ -23,7 +23,13 @@
 #include <utils/FileMap.h>
 #include <utils/Log.h>
 
+#if defined(HAVE_WIN32_FILEMAP) && !defined(__USE_MINGW_ANSI_STDIO)
+# define PRId32 "I32d"
+# define PRIx32 "I32x"
+# define PRId64 "I64d"
+#else
 #include <inttypes.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -169,8 +175,8 @@
             goto try_again;
         }
 
-        ALOGE("mmap(%" PRId64 ",%zu) failed: %s\n",
-            adjOffset, adjLength, strerror(errno));
+        ALOGE("mmap(%lld,%zu) failed: %s\n",
+            (long long)adjOffset, adjLength, strerror(errno));
         return false;
     }
     mBasePtr = ptr;
diff --git a/libutils/LinearAllocator.cpp b/libutils/LinearAllocator.cpp
index a07a291..8b90696 100644
--- a/libutils/LinearAllocator.cpp
+++ b/libutils/LinearAllocator.cpp
@@ -92,7 +92,7 @@
         : mNextPage(0)
     {}
 
-    void* operator new(size_t size, void* buf) { return buf; }
+    void* operator new(size_t /*size*/, void* buf) { return buf; }
 
     void* start() {
         return (void*) (((size_t)this) + sizeof(Page));
@@ -103,7 +103,7 @@
     }
 
 private:
-    Page(const Page& other) {}
+    Page(const Page& /*other*/) {}
     Page* mNextPage;
 };
 
diff --git a/libutils/Printer.cpp b/libutils/Printer.cpp
index 263e740..1dc8632 100644
--- a/libutils/Printer.cpp
+++ b/libutils/Printer.cpp
@@ -25,10 +25,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#ifndef __BIONIC__
-#define fdprintf dprintf
-#endif
-
 namespace android {
 
 /*
@@ -120,7 +116,7 @@
     }
 
 #ifndef USE_MINGW
-    fdprintf(mFd, mFormatString, mPrefix, string);
+    dprintf(mFd, mFormatString, mPrefix, string);
 #endif
 }
 
diff --git a/libutils/RefBase.cpp b/libutils/RefBase.cpp
index 385c226..02907ad 100644
--- a/libutils/RefBase.cpp
+++ b/libutils/RefBase.cpp
@@ -17,6 +17,14 @@
 #define LOG_TAG "RefBase"
 // #define LOG_NDEBUG 0
 
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <typeinfo>
+#include <unistd.h>
+
 #include <utils/RefBase.h>
 
 #include <utils/Atomic.h>
@@ -24,13 +32,9 @@
 #include <utils/Log.h>
 #include <utils/threads.h>
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <typeinfo>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
+#ifndef __unused
+#define __unused __attribute__((__unused__))
+#endif
 
 // compile with refcounting debugging enabled
 #define DEBUG_REFS                      0
@@ -388,7 +392,7 @@
 {
     weakref_impl* const impl = static_cast<weakref_impl*>(this);
     impl->addWeakRef(id);
-    const int32_t c = android_atomic_inc(&impl->mWeak);
+    const int32_t c __unused = android_atomic_inc(&impl->mWeak);
     ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
 }
 
@@ -615,7 +619,7 @@
 {
 }
 
-bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id)
+bool RefBase::onIncStrongAttempted(uint32_t flags, const void* /*id*/)
 {
     return (flags&FIRST_INC_STRONG) ? true : false;
 }
@@ -626,13 +630,15 @@
 
 // ---------------------------------------------------------------------------
 
-void RefBase::renameRefs(size_t n, const ReferenceRenamer& renamer) {
 #if DEBUG_REFS
+void RefBase::renameRefs(size_t n, const ReferenceRenamer& renamer) {
     for (size_t i=0 ; i<n ; i++) {
         renamer(i);
     }
-#endif
 }
+#else
+void RefBase::renameRefs(size_t /*n*/, const ReferenceRenamer& /*renamer*/) { }
+#endif
 
 void RefBase::renameRefId(weakref_type* ref,
         const void* old_id, const void* new_id) {
diff --git a/libutils/StopWatch.cpp b/libutils/StopWatch.cpp
index b1708d6..8c7b596 100644
--- a/libutils/StopWatch.cpp
+++ b/libutils/StopWatch.cpp
@@ -21,7 +21,9 @@
 #include <stdio.h>
 
 /* for PRId64 */
+#ifndef __STDC_FORMAT_MACROS
 #define __STDC_FORMAT_MACROS 1
+#endif
 #include <inttypes.h>
 
 #include <utils/Log.h>
diff --git a/libutils/String16.cpp b/libutils/String16.cpp
index b09b728..91efdaa 100644
--- a/libutils/String16.cpp
+++ b/libutils/String16.cpp
@@ -16,7 +16,6 @@
 
 #include <utils/String16.h>
 
-#include <utils/Debug.h>
 #include <utils/Log.h>
 #include <utils/Unicode.h>
 #include <utils/String8.h>
@@ -67,8 +66,6 @@
         return getEmptyString();
     }
 
-    const uint8_t* const u8end = u8cur + u8len;
-
     SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t)*(u16len+1));
     if (buf) {
         u8cur = (const uint8_t*) u8str;
diff --git a/libutils/String8.cpp b/libutils/String8.cpp
index 1353a9f..9092cbc 100644
--- a/libutils/String8.cpp
+++ b/libutils/String8.cpp
@@ -575,7 +575,6 @@
 {
     const char* lastSlash;
     const char* lastDot;
-    int extLen;
     const char* const str = mString;
 
     // only look at the filename
diff --git a/libutils/SystemClock.cpp b/libutils/SystemClock.cpp
index 413250f..dbad581 100644
--- a/libutils/SystemClock.cpp
+++ b/libutils/SystemClock.cpp
@@ -68,13 +68,7 @@
  */
 #define DEBUG_TIMESTAMP         0
 
-static const char *gettime_method_names[] = {
-    "clock_gettime",
-    "ioctl",
-    "systemTime",
-};
-
-#if DEBUG_TIMESTAMP
+#if DEBUG_TIMESTAMP && defined(ARCH_ARM)
 static inline void checkTimeStamps(int64_t timestamp,
                                    int64_t volatile *prevTimestampPtr,
                                    int volatile *prevMethodPtr,
@@ -85,11 +79,16 @@
      * gettid, and int64_t is different on the ARM platform
      * (ie long vs long long).
      */
-#ifdef ARCH_ARM
     int64_t prevTimestamp = *prevTimestampPtr;
     int prevMethod = *prevMethodPtr;
 
     if (timestamp < prevTimestamp) {
+        static const char *gettime_method_names[] = {
+            "clock_gettime",
+            "ioctl",
+            "systemTime",
+        };
+
         ALOGW("time going backwards: prev %lld(%s) vs now %lld(%s), tid=%d",
               prevTimestamp, gettime_method_names[prevMethod],
               timestamp, gettime_method_names[curMethod],
@@ -99,7 +98,6 @@
     // write is interrupted or not observed as a whole.
     *prevTimestampPtr = timestamp;
     *prevMethodPtr = curMethod;
-#endif
 }
 #else
 #define checkTimeStamps(timestamp, prevTimestampPtr, prevMethodPtr, curMethod)
diff --git a/libutils/Threads.cpp b/libutils/Threads.cpp
index ff74914..cc7fe89 100644
--- a/libutils/Threads.cpp
+++ b/libutils/Threads.cpp
@@ -17,16 +17,11 @@
 // #define LOG_NDEBUG 0
 #define LOG_TAG "libutils.threads"
 
-#include <utils/threads.h>
-#include <utils/Log.h>
-
-#include <cutils/sched_policy.h>
-
+#include <assert.h>
+#include <errno.h>
+#include <memory.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <memory.h>
-#include <errno.h>
-#include <assert.h>
 #include <unistd.h>
 
 #if defined(HAVE_PTHREADS)
@@ -47,6 +42,17 @@
 #include <sys/prctl.h>
 #endif
 
+#include <utils/threads.h>
+#include <utils/Log.h>
+
+#include <cutils/sched_policy.h>
+
+#ifdef HAVE_ANDROID_OS
+# define __android_unused
+#else
+# define __android_unused __attribute__((__unused__))
+#endif
+
 /*
  * ===========================================================================
  *      Thread wrappers
@@ -119,7 +125,7 @@
 
 int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
                                void *userData,
-                               const char* threadName,
+                               const char* threadName __android_unused,
                                int32_t threadPriority,
                                size_t threadStackSize,
                                android_thread_id_t *threadId)
@@ -251,9 +257,9 @@
 
 int androidCreateRawThreadEtc(android_thread_func_t fn,
                                void *userData,
-                               const char* threadName,
-                               int32_t threadPriority,
-                               size_t threadStackSize,
+                               const char* /*threadName*/,
+                               int32_t /*threadPriority*/,
+                               size_t /*threadStackSize*/,
                                android_thread_id_t *threadId)
 {
     return doCreateThread(  fn, userData, threadId);
diff --git a/libutils/Timers.cpp b/libutils/Timers.cpp
index a431e92..4687d4d 100644
--- a/libutils/Timers.cpp
+++ b/libutils/Timers.cpp
@@ -32,9 +32,9 @@
 #include <windows.h>
 #endif
 
+#if defined(HAVE_ANDROID_OS)
 nsecs_t systemTime(int clock)
 {
-#if defined(HAVE_ANDROID_OS)
     static const clockid_t clocks[] = {
             CLOCK_REALTIME,
             CLOCK_MONOTONIC,
@@ -46,7 +46,10 @@
     t.tv_sec = t.tv_nsec = 0;
     clock_gettime(clocks[clock], &t);
     return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
+}
 #else
+nsecs_t systemTime(int /*clock*/)
+{
     // Clock support varies widely across hosts. Mac OS doesn't support
     // posix clocks, older glibcs don't support CLOCK_BOOTTIME and Windows
     // is windows.
@@ -54,8 +57,8 @@
     t.tv_sec = t.tv_usec = 0;
     gettimeofday(&t, NULL);
     return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL;
-#endif
 }
+#endif
 
 int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime)
 {
diff --git a/libutils/Unicode.cpp b/libutils/Unicode.cpp
index a66e3bb..fe8887d 100644
--- a/libutils/Unicode.cpp
+++ b/libutils/Unicode.cpp
@@ -576,7 +576,7 @@
 char16_t* utf8_to_utf16_n(const uint8_t* src, size_t srcLen, char16_t* dst, size_t dstLen) {
     const uint8_t* const u8end = src + srcLen;
     const uint8_t* u8cur = src;
-    const uint16_t* const u16end = dst + dstLen;
+    const char16_t* const u16end = dst + dstLen;
     char16_t* u16cur = dst;
 
     while (u8cur < u8end && u16cur < u16end) {
diff --git a/libutils/tests/BlobCache_test.cpp b/libutils/tests/BlobCache_test.cpp
index 7202123..dac4e2c 100644
--- a/libutils/tests/BlobCache_test.cpp
+++ b/libutils/tests/BlobCache_test.cpp
@@ -44,7 +44,7 @@
 };
 
 TEST_F(BlobCacheTest, CacheSingleValueSucceeds) {
-    char buf[4] = { 0xee, 0xee, 0xee, 0xee };
+    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
     mBC->set("abcd", 4, "efgh", 4);
     ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4));
     ASSERT_EQ('e', buf[0]);
@@ -54,7 +54,7 @@
 }
 
 TEST_F(BlobCacheTest, CacheTwoValuesSucceeds) {
-    char buf[2] = { 0xee, 0xee };
+    unsigned char buf[2] = { 0xee, 0xee };
     mBC->set("ab", 2, "cd", 2);
     mBC->set("ef", 2, "gh", 2);
     ASSERT_EQ(size_t(2), mBC->get("ab", 2, buf, 2));
@@ -66,7 +66,7 @@
 }
 
 TEST_F(BlobCacheTest, GetOnlyWritesInsideBounds) {
-    char buf[6] = { 0xee, 0xee, 0xee, 0xee, 0xee, 0xee };
+    unsigned char buf[6] = { 0xee, 0xee, 0xee, 0xee, 0xee, 0xee };
     mBC->set("abcd", 4, "efgh", 4);
     ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf+1, 4));
     ASSERT_EQ(0xee, buf[0]);
@@ -78,7 +78,7 @@
 }
 
 TEST_F(BlobCacheTest, GetOnlyWritesIfBufferIsLargeEnough) {
-    char buf[3] = { 0xee, 0xee, 0xee };
+    unsigned char buf[3] = { 0xee, 0xee, 0xee };
     mBC->set("abcd", 4, "efgh", 4);
     ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 3));
     ASSERT_EQ(0xee, buf[0]);
@@ -92,7 +92,7 @@
 }
 
 TEST_F(BlobCacheTest, MultipleSetsCacheLatestValue) {
-    char buf[4] = { 0xee, 0xee, 0xee, 0xee };
+    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
     mBC->set("abcd", 4, "efgh", 4);
     mBC->set("abcd", 4, "ijkl", 4);
     ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4));
@@ -103,7 +103,7 @@
 }
 
 TEST_F(BlobCacheTest, SecondSetKeepsFirstValueIfTooLarge) {
-    char buf[MAX_VALUE_SIZE+1] = { 0xee, 0xee, 0xee, 0xee };
+    unsigned char buf[MAX_VALUE_SIZE+1] = { 0xee, 0xee, 0xee, 0xee };
     mBC->set("abcd", 4, "efgh", 4);
     mBC->set("abcd", 4, buf, MAX_VALUE_SIZE+1);
     ASSERT_EQ(size_t(4), mBC->get("abcd", 4, buf, 4));
@@ -115,7 +115,7 @@
 
 TEST_F(BlobCacheTest, DoesntCacheIfKeyIsTooBig) {
     char key[MAX_KEY_SIZE+1];
-    char buf[4] = { 0xee, 0xee, 0xee, 0xee };
+    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
     for (int i = 0; i < MAX_KEY_SIZE+1; i++) {
         key[i] = 'a';
     }
@@ -165,7 +165,7 @@
 
 TEST_F(BlobCacheTest, CacheMaxKeySizeSucceeds) {
     char key[MAX_KEY_SIZE];
-    char buf[4] = { 0xee, 0xee, 0xee, 0xee };
+    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
     for (int i = 0; i < MAX_KEY_SIZE; i++) {
         key[i] = 'a';
     }
@@ -214,7 +214,7 @@
 }
 
 TEST_F(BlobCacheTest, CacheMinKeyAndValueSizeSucceeds) {
-    char buf[1] = { 0xee };
+    unsigned char buf[1] = { 0xee };
     mBC->set("x", 1, "y", 1);
     ASSERT_EQ(size_t(1), mBC->get("x", 1, buf, 1));
     ASSERT_EQ('y', buf[0]);
@@ -282,7 +282,7 @@
 };
 
 TEST_F(BlobCacheFlattenTest, FlattenOneValue) {
-    char buf[4] = { 0xee, 0xee, 0xee, 0xee };
+    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
     mBC->set("abcd", 4, "efgh", 4);
     roundTrip();
     ASSERT_EQ(size_t(4), mBC2->get("abcd", 4, buf, 4));
@@ -348,7 +348,7 @@
 }
 
 TEST_F(BlobCacheFlattenTest, UnflattenCatchesBadMagic) {
-    char buf[4] = { 0xee, 0xee, 0xee, 0xee };
+    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
     mBC->set("abcd", 4, "efgh", 4);
 
     size_t size = mBC->getFlattenedSize();
@@ -365,7 +365,7 @@
 }
 
 TEST_F(BlobCacheFlattenTest, UnflattenCatchesBadBlobCacheVersion) {
-    char buf[4] = { 0xee, 0xee, 0xee, 0xee };
+    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
     mBC->set("abcd", 4, "efgh", 4);
 
     size_t size = mBC->getFlattenedSize();
@@ -384,7 +384,7 @@
 }
 
 TEST_F(BlobCacheFlattenTest, UnflattenCatchesBadBlobCacheDeviceVersion) {
-    char buf[4] = { 0xee, 0xee, 0xee, 0xee };
+    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
     mBC->set("abcd", 4, "efgh", 4);
 
     size_t size = mBC->getFlattenedSize();
@@ -403,7 +403,7 @@
 }
 
 TEST_F(BlobCacheFlattenTest, UnflattenCatchesBufferTooSmall) {
-    char buf[4] = { 0xee, 0xee, 0xee, 0xee };
+    unsigned char buf[4] = { 0xee, 0xee, 0xee, 0xee };
     mBC->set("abcd", 4, "efgh", 4);
 
     size_t size = mBC->getFlattenedSize();
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 6781ebe..df5e3bd 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -44,11 +44,13 @@
 /*
  * Zip file constants.
  */
-static const uint32_t kEOCDSignature    = 0x06054b50;
-static const uint32_t kEOCDLen          = 2;
-static const uint32_t kEOCDNumEntries   = 8;              // offset to #of entries in file
-static const uint32_t kEOCDSize         = 12;             // size of the central directory
-static const uint32_t kEOCDFileOffset   = 16;             // offset to central directory
+static const uint32_t kEOCDSignature     = 0x06054b50;
+static const uint32_t kEOCDLen           = 2;
+static const uint32_t kEOCDNumEntries    = 8;             // number of entries in the archive
+static const uint32_t kEOCDSize          = 12;            // size of the central directory
+static const uint32_t kEOCDFileOffset    = 16;            // offset to central directory
+static const uint32_t kEOCDCommentLen    = 20;            // length of the EOCD comment
+static const uint32_t kEOCDComment       = 22;            // offset of the EOCD comment
 
 static const uint32_t kMaxCommentLen    = 65535;          // longest possible in ushort
 static const uint32_t kMaxEOCDSearch    = (kMaxCommentLen + kEOCDLen);
@@ -378,6 +380,13 @@
   const uint16_t num_entries = get2LE(eocd_ptr + kEOCDNumEntries);
   const off64_t dir_size = get4LE(eocd_ptr + kEOCDSize);
   const off64_t dir_offset = get4LE(eocd_ptr + kEOCDFileOffset);
+  const uint16_t comment_length = get2LE(eocd_ptr + kEOCDCommentLen);
+
+  if (eocd_offset + comment_length + kEOCDComment != file_length) {
+    ALOGW("Zip: %" PRId64 " extraneous bytes at the end of the central directory",
+          (int64_t) (file_length - (eocd_offset + comment_length + kEOCDComment)));
+    return kInvalidFile;
+  }
 
   if (dir_offset + dir_size > eocd_offset) {
     ALOGW("Zip: bad offsets (dir %" PRId64 ", size %" PRId64 ", eocd %" PRId64 ")",
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index 2eb9318..dbf7ebf 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -140,11 +140,7 @@
   CloseArchive(handle);
 }
 
-TEST(ziparchive, EmptyEntries) {
-  char temp_file_pattern[] = "empty_entries_test_XXXXXX";
-  int fd = mkstemp(temp_file_pattern);
-  ASSERT_NE(-1, fd);
-  const uint32_t data[] = {
+static const uint32_t kEmptyEntriesZip[] = {
       0x04034b50, 0x0000000a, 0x63600000, 0x00004438, 0x00000000, 0x00000000,
       0x00090000, 0x6d65001c, 0x2e797470, 0x55747874, 0x03000954, 0x52e25c13,
       0x52e25c24, 0x000b7875, 0x42890401, 0x88040000, 0x50000013, 0x1e02014b,
@@ -152,8 +148,13 @@
       0x00001800, 0x00000000, 0xa0000000, 0x00000081, 0x706d6500, 0x742e7974,
       0x54557478, 0x13030005, 0x7552e25c, 0x01000b78, 0x00428904, 0x13880400,
       0x4b500000, 0x00000605, 0x00010000, 0x004f0001, 0x00430000, 0x00000000 };
-  const ssize_t file_size = 168;
-  ASSERT_EQ(file_size, TEMP_FAILURE_RETRY(write(fd, data, file_size)));
+
+TEST(ziparchive, EmptyEntries) {
+  char temp_file_pattern[] = "empty_entries_test_XXXXXX";
+  int fd = mkstemp(temp_file_pattern);
+  ASSERT_NE(-1, fd);
+  const ssize_t file_size = sizeof(kEmptyEntriesZip);
+  ASSERT_EQ(file_size, TEMP_FAILURE_RETRY(write(fd, kEmptyEntriesZip, file_size)));
 
   ZipArchiveHandle handle;
   ASSERT_EQ(0, OpenArchiveFd(fd, "EmptyEntriesTest", &handle));
@@ -177,6 +178,22 @@
   close(output_fd);
 }
 
+TEST(ziparchive, TrailerAfterEOCD) {
+  char temp_file_pattern[] = "trailer_after_eocd_test_XXXXXX";
+  int fd = mkstemp(temp_file_pattern);
+  ASSERT_NE(-1, fd);
+
+  // Create a file with 8 bytes of random garbage.
+  static const uint8_t trailer[] = { 'A' ,'n', 'd', 'r', 'o', 'i', 'd', 'z' };
+  const ssize_t file_size = sizeof(kEmptyEntriesZip);
+  const ssize_t trailer_size = sizeof(trailer);
+  ASSERT_EQ(file_size, TEMP_FAILURE_RETRY(write(fd, kEmptyEntriesZip, file_size)));
+  ASSERT_EQ(trailer_size, TEMP_FAILURE_RETRY(write(fd, trailer, trailer_size)));
+
+  ZipArchiveHandle handle;
+  ASSERT_GT(0, OpenArchiveFd(fd, "EmptyEntriesTest", &handle));
+}
+
 TEST(ziparchive, ExtractToFile) {
   char kTempFilePattern[] = "zip_archive_input_XXXXXX";
   int fd = mkstemp(kTempFilePattern);
diff --git a/libzipfile/Android.mk b/libzipfile/Android.mk
index 614a460..12a2229 100644
--- a/libzipfile/Android.mk
+++ b/libzipfile/Android.mk
@@ -16,6 +16,8 @@
 
 LOCAL_CFLAGS := -Werror
 
+LOCAL_MULTILIB := both
+
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 # build device static library
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index ed2c241..16fe7ee 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -633,11 +633,6 @@
             dev = dev->next = new log_device_t("crash", false, 'c');
             android::g_devCount++;
         }
-        if (android_name_to_log_id("events") == LOG_ID_EVENTS) {
-            dev = dev->next = new log_device_t("events", true, 'e');
-            android::g_devCount++;
-            needBinary = true;
-        }
     }
 
     if (android::g_logRotateSizeKBytes != 0
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index 0651a92..f8d6162 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -70,6 +70,11 @@
         return rc;
     }
 
+    char *cp;
+    while ((cp = strstr(str, "  "))) {
+        memmove(cp, cp + 1, strlen(cp + 1) + 1);
+    }
+
     if (fdDmesg >= 0) {
         struct iovec iov[2];
 
@@ -88,12 +93,11 @@
 
     static const char audit_str[] = " audit(";
     char *timeptr = strstr(str, audit_str);
-    char *cp;
     if (timeptr
             && ((cp = now.strptime(timeptr + sizeof(audit_str) - 1, "%s.%q")))
             && (*cp == ':')) {
         memcpy(timeptr + sizeof(audit_str) - 1, "0.0", 3);
-        strcpy(timeptr + sizeof(audit_str) - 1 + 3, cp);
+        memmove(timeptr + sizeof(audit_str) - 1 + 3, cp, strlen(cp) + 1);
     } else {
         now.strptime("", ""); // side effect of setting CLOCK_REALTIME
     }
@@ -109,37 +113,88 @@
         }
         tid = pid;
         uid = logbuf->pidToUid(pid);
-        strcpy(pidptr, cp);
+        memmove(pidptr, cp, strlen(cp) + 1);
     }
 
-    size_t n = strlen(str);
-    n += sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t);
+    // log to events
+
+    size_t l = strlen(str);
+    size_t n = l + sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t);
+
+    bool notify = false;
 
     char *newstr = reinterpret_cast<char *>(malloc(n));
     if (!newstr) {
-        free(str);
-        return -ENOMEM;
+        rc = -ENOMEM;
+    } else {
+        cp = newstr;
+        *cp++ = AUDITD_LOG_TAG & 0xFF;
+        *cp++ = (AUDITD_LOG_TAG >> 8) & 0xFF;
+        *cp++ = (AUDITD_LOG_TAG >> 16) & 0xFF;
+        *cp++ = (AUDITD_LOG_TAG >> 24) & 0xFF;
+        *cp++ = EVENT_TYPE_STRING;
+        *cp++ = l & 0xFF;
+        *cp++ = (l >> 8) & 0xFF;
+        *cp++ = (l >> 16) & 0xFF;
+        *cp++ = (l >> 24) & 0xFF;
+        memcpy(cp, str, l);
+
+        logbuf->log(LOG_ID_EVENTS, now, uid, pid, tid, newstr,
+                    (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX);
+        free(newstr);
+
+        notify = true;
     }
 
-    char *msg = newstr;
-    *msg++ = AUDITD_LOG_TAG & 0xFF;
-    *msg++ = (AUDITD_LOG_TAG >> 8) & 0xFF;
-    *msg++ = (AUDITD_LOG_TAG >> 16) & 0xFF;
-    *msg++ = (AUDITD_LOG_TAG >> 24) & 0xFF;
-    *msg++ = EVENT_TYPE_STRING;
-    size_t l = n - sizeof(uint32_t) - sizeof(uint8_t) - sizeof(uint32_t);
-    *msg++ = l & 0xFF;
-    *msg++ = (l >> 8) & 0xFF;
-    *msg++ = (l >> 16) & 0xFF;
-    *msg++ = (l >> 24) & 0xFF;
-    memcpy(msg, str, l);
+    // log to main
+
+    static const char comm_str[] = " comm=\"";
+    const char *comm = strstr(str, comm_str);
+    const char *estr = str + strlen(str);
+    if (comm) {
+        estr = comm;
+        comm += sizeof(comm_str) - 1;
+    } else if (pid == getpid()) {
+        pid = tid;
+        comm = "auditd";
+    } else if (!(comm = logbuf->pidToName(pid))) {
+        comm = "unknown";
+    }
+
+    const char *ecomm = strchr(comm, '"');
+    if (ecomm) {
+        ++ecomm;
+        l = ecomm - comm;
+    } else {
+        l = strlen(comm) + 1;
+        ecomm = "";
+    }
+    n = (estr - str) + strlen(ecomm) + l + 2;
+
+    newstr = reinterpret_cast<char *>(malloc(n));
+    if (!newstr) {
+        rc = -ENOMEM;
+    } else {
+        *newstr = (strstr(str, " permissive=1")
+                || strstr(str, " policy loaded "))
+                    ? ANDROID_LOG_INFO
+                    : ANDROID_LOG_WARN;
+        strlcpy(newstr + 1, comm, l);
+        strncpy(newstr + 1 + l, str, estr - str);
+        strcpy(newstr + 1 + l + (estr - str), ecomm);
+
+        logbuf->log(LOG_ID_MAIN, now, uid, pid, tid, newstr,
+                    (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX);
+        free(newstr);
+
+        notify = true;
+    }
+
     free(str);
 
-    logbuf->log(LOG_ID_EVENTS, now, uid, pid, tid, newstr,
-                (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX);
-    reader->notifyNewLog();
-
-    free(newstr);
+    if (notify) {
+        reader->notifyNewLog();
+    }
 
     return rc;
 }
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index ae167aa..0448afa 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -174,7 +174,7 @@
     if (last == mLogElements.end()) {
         mLogElements.push_back(elem);
     } else {
-        log_time end;
+        log_time end = log_time::EPOCH;
         bool end_set = false;
         bool end_always = false;
 
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
index 1a9a548..e7e3ec2 100644
--- a/logd/LogTimes.cpp
+++ b/logd/LogTimes.cpp
@@ -193,6 +193,7 @@
 
     if (me->skipAhead) {
         me->skipAhead--;
+        goto skip;
     }
 
     me->mStart = element->getMonotonicTime();
diff --git a/reboot/Android.mk b/reboot/Android.mk
index 4db0c1e..7a24f99 100644
--- a/reboot/Android.mk
+++ b/reboot/Android.mk
@@ -1,12 +1,14 @@
 # Copyright 2013 The Android Open Source Project
 
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= reboot.c
+LOCAL_SRC_FILES := reboot.c
 
-LOCAL_SHARED_LIBRARIES:= libcutils
+LOCAL_SHARED_LIBRARIES := libcutils
 
-LOCAL_MODULE:= reboot
+LOCAL_MODULE := reboot
+
+LOCAL_CFLAGS := -Werror
 
 include $(BUILD_EXECUTABLE)
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 4bccdd8..606686c 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -102,7 +102,6 @@
     write /proc/sys/kernel/sched_child_runs_first 0
     write /proc/sys/kernel/randomize_va_space 2
     write /proc/sys/kernel/kptr_restrict 2
-    write /proc/sys/kernel/dmesg_restrict 1
     write /proc/sys/vm/mmap_min_addr 32768
     write /proc/sys/net/ipv4/ping_group_range "0 2147483647"
     write /proc/sys/net/unix/max_dgram_qlen 300
@@ -236,12 +235,14 @@
     mkdir /data/misc/sms 0770 system radio
     mkdir /data/misc/zoneinfo 0775 system system
     mkdir /data/misc/vpn 0770 system vpn
+    mkdir /data/misc/shared_relro 0771 shared_relro shared_relro
     mkdir /data/misc/systemkeys 0700 system system
     mkdir /data/misc/wifi 0770 wifi wifi
     mkdir /data/misc/wifi/sockets 0770 wifi wifi
     mkdir /data/misc/wifi/wpa_supplicant 0770 wifi wifi
     mkdir /data/misc/ethernet 0770 system system
     mkdir /data/misc/dhcp 0770 dhcp dhcp
+    mkdir /data/misc/user 0771 root root
     # give system access to wpa_supplicant.conf for backup and restore
     chmod 0660 /data/misc/wifi/wpa_supplicant.conf
     mkdir /data/local 0751 root root
diff --git a/rootdir/init.zygote64_32.rc b/rootdir/init.zygote64_32.rc
new file mode 100644
index 0000000..979ab3b
--- /dev/null
+++ b/rootdir/init.zygote64_32.rc
@@ -0,0 +1,12 @@
+service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
+    class main
+    socket zygote stream 660 root system
+    onrestart write /sys/android_power/request_state wake
+    onrestart write /sys/power/state on
+    onrestart restart media
+    onrestart restart netd
+
+service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
+    class main
+    socket zygote_secondary stream 660 root system
+    onrestart restart zygote
diff --git a/sdcard/Android.mk b/sdcard/Android.mk
index 4630db9..63b0f41 100644
--- a/sdcard/Android.mk
+++ b/sdcard/Android.mk
@@ -1,10 +1,10 @@
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= sdcard.c
-LOCAL_MODULE:= sdcard
-LOCAL_CFLAGS := -Wall -Wno-unused-parameter
+LOCAL_SRC_FILES := sdcard.c
+LOCAL_MODULE := sdcard
+LOCAL_CFLAGS := -Wall -Wno-unused-parameter -Werror
 
 LOCAL_SHARED_LIBRARIES := libc libcutils
 
diff --git a/toolbox/watchprops.c b/toolbox/watchprops.c
index 06cdebe..0d05aba 100644
--- a/toolbox/watchprops.c
+++ b/toolbox/watchprops.c
@@ -6,8 +6,6 @@
 #include <cutils/properties.h>
 #include <cutils/hashmap.h>
 
-#include <sys/atomics.h>
-
 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
 #include <sys/_system_properties.h>