Merge "Create world-searchable /data/misc/user directory"
diff --git a/adb/Android.mk b/adb/Android.mk
index 62f012c..50e28a6 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -74,7 +74,7 @@
   LOCAL_SRC_FILES += fdevent.c
 endif
 
-LOCAL_CFLAGS += -O2 -g -DADB_HOST=1  -Wall -Wno-unused-parameter
+LOCAL_CFLAGS += -O2 -g -DADB_HOST=1 -Wall -Wno-unused-parameter -Werror
 LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
 LOCAL_MODULE := adb
 LOCAL_MODULE_TAGS := debug
@@ -116,7 +116,7 @@
 	remount_service.c \
 	usb_linux_client.c
 
-LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
+LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter -Werror
 LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
 
 ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
@@ -138,8 +138,6 @@
 ifneq ($(SDK_ONLY),true)
 include $(CLEAR_VARS)
 
-LOCAL_LDLIBS := -lrt -ldl -lpthread
-
 LOCAL_SRC_FILES := \
 	adb.c \
 	console.c \
@@ -162,8 +160,7 @@
 	-g \
 	-DADB_HOST=1 \
 	-DADB_HOST_ON_TARGET=1 \
-	-Wall \
-	-Wno-unused-parameter \
+	-Wall -Wno-unused-parameter -Werror \
 	-D_XOPEN_SOURCE \
 	-D_GNU_SOURCE
 
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 0e41b34..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;
@@ -1347,12 +1358,11 @@
         ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
         ** AID_SDCARD_R to allow reading from the SD card
         ** AID_SDCARD_RW to allow writing to the SD card
-        ** AID_MOUNT to allow unmounting the SD card before rebooting
         ** AID_NET_BW_STATS to read out qtaguid statistics
         */
         gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
                            AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
-                           AID_MOUNT, AID_NET_BW_STATS };
+                           AID_NET_BW_STATS };
         if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
             exit(1);
         }
@@ -1428,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;
@@ -1548,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..2504f99 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -323,6 +323,8 @@
 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,
diff --git a/adb/adb_auth_host.c b/adb/adb_auth_host.c
index 9039d42..783774a 100644
--- a/adb/adb_auth_host.c
+++ b/adb/adb_auth_host.c
@@ -159,13 +159,13 @@
 
     bio = BIO_push(b64, bfile);
     BIO_write(bio, &pkey, sizeof(pkey));
-    BIO_flush(bio);
+    (void) BIO_flush(bio);
     BIO_pop(b64);
     BIO_free(b64);
 
     get_user_info(info, sizeof(info));
     BIO_write(bfile, info, strlen(info));
-    BIO_flush(bfile);
+    (void) BIO_flush(bfile);
     BIO_free_all(bfile);
 
     return 1;
diff --git a/adb/backup_service.c b/adb/backup_service.c
index 669ff86..654e0f3 100644
--- a/adb/backup_service.c
+++ b/adb/backup_service.c
@@ -52,15 +52,12 @@
     pid_t pid;
     int s[2];
     char* operation;
-    int socketnum;
 
-    // Command string and choice of stdin/stdout for the pipe depend on our invocation
+    // Command string depends on our invocation
     if (op == BACKUP) {
         operation = "backup";
-        socketnum = STDOUT_FILENO;
     } else {
         operation = "restore";
-        socketnum = STDIN_FILENO;
     }
 
     D("backup_service(%s, %s)\n", operation, args);
diff --git a/adb/commandline.c b/adb/commandline.c
index 83b568d..18dc6e0 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -136,6 +136,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] [-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"
@@ -406,7 +419,7 @@
     }
 
     int opt = CHUNK_SIZE;
-    opt = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt));
+    opt = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
 
     total = sz;
     ptr = data;
@@ -681,10 +694,10 @@
     return 0;
 }
 
-static int mkdirs(char *path)
+static int mkdirs(const char *path)
 {
     int ret;
-    char *x = path + 1;
+    char *x = (char *)path + 1;
 
     for(;;) {
         x = adb_dirstart(x);
@@ -727,7 +740,7 @@
     if (argc < 2) return usage();
 
     adb_unlink(filename);
-    mkdirs((char *)filename);
+    mkdirs(filename);
     outFd = adb_creat(filename, 0640);
     if (outFd < 0) {
         fprintf(stderr, "adb: unable to open file %s\n", filename);
@@ -1299,8 +1312,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;
@@ -1329,15 +1345,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
@@ -1723,6 +1743,8 @@
         } else if (!strcmp(argv[i], "--key")) {
             verify_apk = 0;
             i++;
+        } else if (!strcmp(argv[i], "--abi")) {
+            i++;
         }
     }
 
diff --git a/adb/file_sync_client.c b/adb/file_sync_client.c
index 8fad50e..dc4e77f 100644
--- a/adb/file_sync_client.c
+++ b/adb/file_sync_client.c
@@ -456,10 +456,10 @@
     return -1;
 }
 
-static int mkdirs(char *name)
+static int mkdirs(const char *name)
 {
     int ret;
-    char *x = name + 1;
+    char *x = (char *)name + 1;
 
     for(;;) {
         x = adb_dirstart(x);
@@ -521,7 +521,7 @@
 
     if((id == ID_DATA) || (id == ID_DONE)) {
         adb_unlink(lpath);
-        mkdirs((char *)lpath);
+        mkdirs(lpath);
         lfd = adb_creat(lpath, 0644);
         if(lfd < 0) {
             fprintf(stderr,"cannot create '%s': %s\n", lpath, strerror(errno));
diff --git a/adb/remount_service.c b/adb/remount_service.c
index ad61284..d3a649b 100644
--- a/adb/remount_service.c
+++ b/adb/remount_service.c
@@ -14,13 +14,13 @@
  * limitations under the License.
  */
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/mount.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <unistd.h>
 
 #include "sysdeps.h"
 
@@ -35,7 +35,6 @@
 {
     int fd;
     int res;
-    int size;
     char *token = NULL;
     const char delims[] = "\n";
     char buf[4096];
@@ -45,7 +44,7 @@
         return NULL;
 
     buf[sizeof(buf) - 1] = '\0';
-    size = adb_read(fd, buf, sizeof(buf) - 1);
+    adb_read(fd, buf, sizeof(buf) - 1);
     adb_close(fd);
 
     token = strtok(buf, delims);
diff --git a/adb/services.c b/adb/services.c
index 5b63a43..7b809da 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -116,23 +116,10 @@
 {
     char buf[100];
     char property_val[PROPERTY_VALUE_MAX];
-    int pid, ret;
+    int ret;
 
     sync();
 
-    /* Attempt to unmount the SD card first.
-     * No need to bother checking for errors.
-     */
-    pid = fork();
-    if (pid == 0) {
-        /* ask vdc to unmount it */
-        execl("/system/bin/vdc", "/system/bin/vdc", "volume", "unmount",
-                getenv("EXTERNAL_STORAGE"), "force", NULL);
-    } else if (pid > 0) {
-        /* wait until vdc succeeds or fails */
-        waitpid(pid, &ret, 0);
-    }
-
     ret = snprintf(property_val, sizeof(property_val), "reboot,%s", (char *) arg);
     if (ret >= (int) sizeof(property_val)) {
         snprintf(buf, sizeof(buf), "reboot string too long. length=%d\n", ret);
@@ -154,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)
@@ -398,6 +396,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) {
@@ -460,7 +468,7 @@
 
     snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port);
 
-    fd = socket_network_client(hostbuf, port, SOCK_STREAM);
+    fd = socket_network_client_timeout(hostbuf, port, SOCK_STREAM, 10);
     if (fd < 0) {
         snprintf(buffer, buffer_size, "unable to connect to %s:%d", host, port);
         return;
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 4033b72..ba4306f 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -169,6 +169,8 @@
 /* normally provided by <cutils/sockets.h> */
 extern int socket_loopback_client(int port, int type);
 extern int socket_network_client(const char *host, int port, int type);
+extern int socket_network_client_timeout(const char *host, int port, int type,
+                                         int timeout);
 extern int socket_loopback_server(int port, int type);
 extern int socket_inaddr_any_server(int port, int type);
 
diff --git a/adb/sysdeps_win32.c b/adb/sysdeps_win32.c
index 2105b16..29f58ec 100644
--- a/adb/sysdeps_win32.c
+++ b/adb/sysdeps_win32.c
@@ -701,6 +701,13 @@
 }
 
 
+int socket_network_client_timeout(const char *host, int port, int type, int timeout)
+{
+    // TODO: implement timeouts for Windows.
+    return socket_network_client(host, port, type);
+}
+
+
 int socket_inaddr_any_server(int port, int type)
 {
     FH  f = _fh_alloc( &_fh_socket_class );
@@ -956,7 +963,7 @@
             avail = len;
 
         memcpy( bip->buff + bip->a_end, src, avail );
-        src   += avail;
+        src   = (const char *)src + avail;
         count += avail;
         len   -= avail;
 
@@ -1049,7 +1056,7 @@
         avail = len;
 
     memcpy( dst, bip->buff + bip->a_start, avail );
-    dst   += avail;
+    dst   = (char *)dst + avail;
     count += avail;
     len   -= avail;
 
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index 0c46a0c..c7e0ad5 100755
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -51,7 +51,9 @@
 // BYD's USB Vendor ID
 #define VENDOR_ID_BYD           0x1D91
 // Compal's USB Vendor ID
-#define VENDOR_ID_COMPAL        0x1219
+#define VENDOR_ID_COMPAL        0x04B7
+// Compalcomm's USB Vendor ID
+#define VENDOR_ID_COMPALCOMM    0x1219
 // Dell's USB Vendor ID
 #define VENDOR_ID_DELL          0x413c
 // ECS's USB Vendor ID
@@ -170,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
@@ -195,6 +199,7 @@
     VENDOR_ID_ASUS,
     VENDOR_ID_BYD,
     VENDOR_ID_COMPAL,
+    VENDOR_ID_COMPALCOMM,
     VENDOR_ID_DELL,
     VENDOR_ID_ECS,
     VENDOR_ID_EMERGING_TECH,
@@ -254,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/adb/usb_windows.c b/adb/usb_windows.c
index 4936b77..1309a78 100644
--- a/adb/usb_windows.c
+++ b/adb/usb_windows.c
@@ -310,14 +310,14 @@
       int xfer = (len > 4096) ? 4096 : len;
 
       ret = AdbReadEndpointSync(handle->adb_read_pipe,
-                                  (void*)data,
+                                  data,
                                   (unsigned long)xfer,
                                   &read,
                                   time_out);
       int saved_errno = GetLastError();
       D("usb_write got: %ld, expected: %d, errno: %d\n", read, xfer, saved_errno);
       if (ret) {
-        data += read;
+        data = (char *)data + read;
         len -= read;
 
         if (len == 0)
diff --git a/adf/libadf/adf.c b/adf/libadf/adf.c
index 871629e..1d19152 100644
--- a/adf/libadf/adf.c
+++ b/adf/libadf/adf.c
@@ -768,7 +768,7 @@
         const __u32 *formats, size_t n_formats,
         adf_id_t *interface, adf_id_t *overlay_engine)
 {
-    adf_id_t *intfs;
+    adf_id_t *intfs = NULL;
     ssize_t n_intfs = adf_interfaces(dev, &intfs);
 
     if (n_intfs < 0)
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 f6d8f0c..e4d7ecc 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -3,25 +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 \
-	-Wno-unused-parameter \
+LOCAL_CPPFLAGS := \
+    -std=gnu++11 \
+    -W -Wall -Wextra \
+    -Wunused \
+    -Werror \
 
 ifeq ($(ARCH_ARM_HAVE_VFP),true)
 LOCAL_CFLAGS_arm += -DWITH_VFP
@@ -31,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
 
@@ -43,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)
 
@@ -51,11 +50,12 @@
 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)
 LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS += -fstack-protector-all -Wno-unused-parameter -Wno-free-nonheap-object
+LOCAL_CFLAGS += -fstack-protector-all -Werror -Wno-free-nonheap-object
 #LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_SHARED_LIBRARIES := libcutils liblog libc
 
@@ -76,6 +76,7 @@
 LOCAL_CFLAGS_arm += -DWITH_VFP_D32
 endif # ARCH_ARM_HAVE_VFP_D32
 endif # ARCH_ARM_HAVE_VFP == true
+LOCAL_CFLAGS += -Werror
 
 LOCAL_SRC_FILES_arm64 := arm64/vfp.S
 LOCAL_MODULE_TARGET_ARCH += arm64
diff --git a/debuggerd/arm64/machine.cpp b/debuggerd/arm64/machine.cpp
index 7159228..2413d5e 100644
--- a/debuggerd/arm64/machine.cpp
+++ b/debuggerd/arm64/machine.cpp
@@ -82,8 +82,6 @@
   io.iov_base = &r;
   io.iov_len = sizeof(r);
 
-  bool only_in_tombstone = !IS_AT_FAULT(scope_flags);
-
   if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRSTATUS, (void*) &io) == -1) {
     _LOG(log, scope_flags, "ptrace error: %s\n", strerror(errno));
     return;
diff --git a/debuggerd/crasher.c b/debuggerd/crasher.c
index 9946faa..4721da9 100644
--- a/debuggerd/crasher.c
+++ b/debuggerd/crasher.c
@@ -6,13 +6,18 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/cdefs.h>
 #include <sys/ptrace.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
-#include <cutils/log.h>
 #include <cutils/sockets.h>
+#include <log/log.h>
+
+#ifndef __unused
+#define __unused __attribute__((__unused__))
+#endif
 
 extern const char* __progname;
 
@@ -26,7 +31,7 @@
     }
 }
 
-static int smash_stack(int i) {
+static int smash_stack(int i __unused) {
     printf("crasher: deliberately corrupting stack...\n");
     // Unless there's a "big enough" buffer on the stack, gcc
     // doesn't bother inserting checks.
@@ -47,11 +52,6 @@
     overflow_stack(&buf);
 }
 
-static void test_call1()
-{
-    *((int*) 32) = 1;
-}
-
 static void *noisy(void *x)
 {
     char c = (uintptr_t) x;
@@ -126,7 +126,7 @@
         return ctest();
     } else if (!strcmp(arg, "exit")) {
         exit(1);
-    } else if (!strcmp(arg, "crash")) {
+    } else if (!strcmp(arg, "crash") || !strcmp(arg, "SIGSEGV")) {
         return crash(42);
     } else if (!strcmp(arg, "abort")) {
         maybe_abort();
@@ -138,23 +138,36 @@
         LOG_ALWAYS_FATAL("hello %s", "world");
     } else if (!strcmp(arg, "LOG_ALWAYS_FATAL_IF")) {
         LOG_ALWAYS_FATAL_IF(true, "hello %s", "world");
+    } else if (!strcmp(arg, "SIGPIPE")) {
+        int pipe_fds[2];
+        pipe(pipe_fds);
+        close(pipe_fds[0]);
+        write(pipe_fds[1], "oops", 4);
+        return EXIT_SUCCESS;
+    } else if (!strcmp(arg, "SIGTRAP")) {
+        raise(SIGTRAP);
+        return EXIT_SUCCESS;
     } else if (!strcmp(arg, "heap-usage")) {
         abuse_heap();
     }
 
     fprintf(stderr, "%s OP\n", __progname);
     fprintf(stderr, "where OP is:\n");
-    fprintf(stderr, "  smash-stack     overwrite a stack-guard canary\n");
-    fprintf(stderr, "  stack-overflow  recurse until the stack overflows\n");
-    fprintf(stderr, "  heap-corruption cause a libc abort by corrupting the heap\n");
-    fprintf(stderr, "  heap-usage      cause a libc abort by abusing a heap function\n");
-    fprintf(stderr, "  nostack         crash with a NULL stack pointer\n");
-    fprintf(stderr, "  ctest           (obsoleted by thread-crash?)\n");
-    fprintf(stderr, "  exit            call exit(1)\n");
-    fprintf(stderr, "  crash           cause a SIGSEGV\n");
-    fprintf(stderr, "  abort           call abort()\n");
-    fprintf(stderr, "  assert          call assert() without a function\n");
-    fprintf(stderr, "  assert2         call assert() with a function\n");
+    fprintf(stderr, "  smash-stack           overwrite a stack-guard canary\n");
+    fprintf(stderr, "  stack-overflow        recurse until the stack overflows\n");
+    fprintf(stderr, "  heap-corruption       cause a libc abort by corrupting the heap\n");
+    fprintf(stderr, "  heap-usage            cause a libc abort by abusing a heap function\n");
+    fprintf(stderr, "  nostack               crash with a NULL stack pointer\n");
+    fprintf(stderr, "  ctest                 (obsoleted by thread-crash?)\n");
+    fprintf(stderr, "  exit                  call exit(1)\n");
+    fprintf(stderr, "  abort                 call abort()\n");
+    fprintf(stderr, "  assert                call assert() without a function\n");
+    fprintf(stderr, "  assert2               call assert() with a function\n");
+    fprintf(stderr, "  LOG_ALWAYS_FATAL      call LOG_ALWAYS_FATAL\n");
+    fprintf(stderr, "  LOG_ALWAYS_FATAL_IF   call LOG_ALWAYS_FATAL\n");
+    fprintf(stderr, "  SIGPIPE               cause a SIGPIPE\n");
+    fprintf(stderr, "  SIGSEGV               cause a SIGSEGV (synonym: crash)\n");
+    fprintf(stderr, "  SIGTRAP               cause a SIGTRAP\n");
     fprintf(stderr, "prefix any of the above with 'thread-' to not run\n");
     fprintf(stderr, "on the process' main thread.\n");
     return EXIT_SUCCESS;
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index a2b164e..3726c38 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -51,99 +51,59 @@
   pid_t pid, tid;
   uid_t uid, gid;
   uintptr_t abort_msg_address;
+  int32_t original_si_code;
 };
 
-static int write_string(const char* file, const char* string) {
-  int len;
-  int fd;
-  ssize_t amt;
-  fd = open(file, O_RDWR);
-  len = strlen(string);
-  if (fd < 0)
-    return -errno;
-  amt = write(fd, string, len);
-  close(fd);
-  return amt >= 0 ? 0 : -errno;
-}
-
-static void init_debug_led() {
-  // trout leds
-  write_string("/sys/class/leds/red/brightness", "0");
-  write_string("/sys/class/leds/green/brightness", "0");
-  write_string("/sys/class/leds/blue/brightness", "0");
-  write_string("/sys/class/leds/red/device/blink", "0");
-  // sardine leds
-  write_string("/sys/class/leds/left/cadence", "0,0");
-}
-
-static void enable_debug_led() {
-  // trout leds
-  write_string("/sys/class/leds/red/brightness", "255");
-  // sardine leds
-  write_string("/sys/class/leds/left/cadence", "1,0");
-}
-
-static void disable_debug_led() {
-  // trout leds
-  write_string("/sys/class/leds/red/brightness", "0");
-  // sardine leds
-  write_string("/sys/class/leds/left/cadence", "0,0");
-}
-
 static void wait_for_user_action(pid_t pid) {
-  // First log a helpful message
+  // Find out the name of the process that crashed.
+  char path[64];
+  snprintf(path, sizeof(path), "/proc/%d/exe", pid);
+
+  char exe[PATH_MAX];
+  int count;
+  if ((count = readlink(path, exe, sizeof(exe) - 1)) == -1) {
+    LOG("readlink('%s') failed: %s", path, strerror(errno));
+    strlcpy(exe, "unknown", sizeof(exe));
+  } else {
+    exe[count] = '\0';
+  }
+
+  // Turn "/system/bin/app_process" into "app_process".
+  // gdbserver doesn't cope with full paths (though we should fix that
+  // and remove this).
+  char* name = strrchr(exe, '/');
+  if (name == NULL) {
+    name = exe; // No '/' found.
+  } else {
+    ++name; // Skip the '/'.
+  }
+
+  // Explain how to attach the debugger.
   LOG(    "********************************************************\n"
-          "* Process %d has been suspended while crashing.  To\n"
-          "* attach gdbserver for a gdb connection on port 5039\n"
+          "* Process %d has been suspended while crashing.\n"
+          "* To attach gdbserver for a gdb connection on port 5039\n"
           "* and start gdbclient:\n"
           "*\n"
-          "*     gdbclient app_process :5039 %d\n"
+          "*     gdbclient %s :5039 %d\n"
           "*\n"
-          "* Wait for gdb to start, then press HOME or VOLUME DOWN key\n"
+          "* Wait for gdb to start, then press the VOLUME DOWN key\n"
           "* to let the process continue crashing.\n"
           "********************************************************\n",
-          pid, pid);
+          pid, name, pid);
 
-  // wait for HOME or VOLUME DOWN key
+  // Wait for VOLUME DOWN.
   if (init_getevent() == 0) {
-    int ms = 1200 / 10;
-    int dit = 1;
-    int dah = 3*dit;
-    int _       = -dit;
-    int ___     = 3*_;
-    int _______ = 7*_;
-    const int codes[] = {
-      dit,_,dit,_,dit,___,dah,_,dah,_,dah,___,dit,_,dit,_,dit,_______
-    };
-    size_t s = 0;
-    input_event e;
-    bool done = false;
-    init_debug_led();
-    enable_debug_led();
-    do {
-      int timeout = abs(codes[s]) * ms;
-      int res = get_event(&e, timeout);
-      if (res == 0) {
-        if (e.type == EV_KEY
-            && (e.code == KEY_HOME || e.code == KEY_VOLUMEDOWN)
-            && e.value == 0) {
-          done = true;
-        }
-      } else if (res == 1) {
-        if (++s >= sizeof(codes)/sizeof(*codes))
-          s = 0;
-        if (codes[s] > 0) {
-          enable_debug_led();
-        } else {
-          disable_debug_led();
+    while (true) {
+      input_event e;
+      if (get_event(&e, -1) == 0) {
+        if (e.type == EV_KEY && e.code == KEY_VOLUMEDOWN && e.value == 0) {
+          break;
         }
       }
-    } while (!done);
+    }
     uninit_getevent();
   }
 
-  // don't forget to turn debug led off
-  disable_debug_led();
   LOG("debuggerd resuming process %d", pid);
 }
 
@@ -218,6 +178,7 @@
   out_request->uid = cr.uid;
   out_request->gid = cr.gid;
   out_request->abort_msg_address = msg.abort_msg_address;
+  out_request->original_si_code = msg.original_si_code;
 
   if (msg.action == DEBUGGER_ACTION_CRASH) {
     // Ensure that the tid reported by the crashing process is valid.
@@ -302,9 +263,10 @@
             case SIGSTOP:
               if (request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
                 XLOG("stopped -- dumping to tombstone\n");
-                tombstone_path = engrave_tombstone(
-                    request.pid, request.tid, signal, request.abort_msg_address, true, true,
-                    &detach_failed, &total_sleep_time_usec);
+                tombstone_path = engrave_tombstone(request.pid, request.tid,
+                                                   signal, request.original_si_code,
+                                                   request.abort_msg_address, true, true,
+                                                   &detach_failed, &total_sleep_time_usec);
               } else if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE) {
                 XLOG("stopped -- dumping to fd\n");
                 dump_backtrace(fd, -1, request.pid, request.tid, &detach_failed,
@@ -319,15 +281,16 @@
               }
               break;
 
-            case SIGILL:
             case SIGABRT:
             case SIGBUS:
             case SIGFPE:
-            case SIGSEGV:
+            case SIGILL:
             case SIGPIPE:
+            case SIGSEGV:
 #ifdef SIGSTKFLT
             case SIGSTKFLT:
 #endif
+            case SIGTRAP:
               XLOG("stopped -- fatal signal\n");
               // Send a SIGSTOP to the process to make all of
               // the non-signaled threads stop moving.  Without
@@ -336,9 +299,10 @@
               kill(request.pid, SIGSTOP);
               // don't dump sibling threads when attaching to GDB because it
               // makes the process less reliable, apparently...
-              tombstone_path = engrave_tombstone(
-                  request.pid, request.tid, signal, request.abort_msg_address, !attach_gdb,
-                  false, &detach_failed, &total_sleep_time_usec);
+              tombstone_path = engrave_tombstone(request.pid, request.tid,
+                                                 signal, request.original_si_code,
+                                                 request.abort_msg_address, !attach_gdb, false,
+                                                 &detach_failed, &total_sleep_time_usec);
               break;
 
             default:
@@ -402,38 +366,36 @@
 }
 
 static int do_server() {
-  int s;
-  struct sigaction act;
-  int logsocket = -1;
-
-  // debuggerd crashes can't be reported to debuggerd.  Reset all of the
-  // crash handlers.
-  signal(SIGILL, SIG_DFL);
+  // debuggerd crashes can't be reported to debuggerd.
+  // Reset all of the crash handlers.
   signal(SIGABRT, SIG_DFL);
   signal(SIGBUS, SIG_DFL);
   signal(SIGFPE, SIG_DFL);
+  signal(SIGILL, SIG_DFL);
   signal(SIGSEGV, SIG_DFL);
 #ifdef SIGSTKFLT
   signal(SIGSTKFLT, SIG_DFL);
 #endif
+  signal(SIGTRAP, SIG_DFL);
 
   // Ignore failed writes to closed sockets
   signal(SIGPIPE, SIG_IGN);
 
-  logsocket = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_DGRAM);
+  int logsocket = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_DGRAM);
   if (logsocket < 0) {
     logsocket = -1;
   } else {
     fcntl(logsocket, F_SETFD, FD_CLOEXEC);
   }
 
+  struct sigaction act;
   act.sa_handler = SIG_DFL;
   sigemptyset(&act.sa_mask);
   sigaddset(&act.sa_mask,SIGCHLD);
   act.sa_flags = SA_NOCLDWAIT;
   sigaction(SIGCHLD, &act, 0);
 
-  s = socket_local_server(DEBUGGER_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
+  int s = socket_local_server(DEBUGGER_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
   if (s < 0)
     return 1;
   fcntl(s, F_SETFD, FD_CLOEXEC);
diff --git a/debuggerd/mips/machine.cpp b/debuggerd/mips/machine.cpp
index 7b4e29e..5c82d4d 100644
--- a/debuggerd/mips/machine.cpp
+++ b/debuggerd/mips/machine.cpp
@@ -22,8 +22,6 @@
 #include <sys/types.h>
 #include <sys/ptrace.h>
 
-#include <corkscrew/ptrace.h>
-
 #include <sys/user.h>
 
 #include "../utility.h"
@@ -34,6 +32,18 @@
 
 #define R(x) (static_cast<unsigned int>(x))
 
+// The MIPS uapi ptrace.h has the wrong definition for pt_regs. PTRACE_GETREGS
+// writes 64-bit quantities even though the public struct uses 32-bit ones.
+struct pt_regs_mips_t {
+  uint64_t regs[32];
+  uint64_t lo;
+  uint64_t hi;
+  uint64_t cp0_epc;
+  uint64_t cp0_badvaddr;
+  uint64_t cp0_status;
+  uint64_t cp0_cause;
+};
+
 // If configured to do so, dump memory around *all* registers
 // for the crashing thread.
 void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index 83df37f..fb5f02a 100755
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -31,9 +31,10 @@
 
 #include <private/android_filesystem_config.h>
 
+#include <cutils/properties.h>
 #include <log/log.h>
 #include <log/logger.h>
-#include <cutils/properties.h>
+#include <log/logprint.h>
 
 #include <backtrace/Backtrace.h>
 #include <backtrace/BacktraceMap.h>
@@ -55,12 +56,27 @@
 // Must match the path defined in NativeCrashListener.java
 #define NCRASH_SOCKET_PATH "/data/system/ndebugsocket"
 
-static bool signal_has_address(int sig) {
+// 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 SIGILL:
-    case SIGFPE:
-    case SIGSEGV:
     case SIGBUS:
+    case SIGFPE:
+    case SIGILL:
+    case SIGSEGV:
       return true;
     default:
       return false;
@@ -69,16 +85,17 @@
 
 static const char* get_signame(int sig) {
   switch(sig) {
-    case SIGILL: return "SIGILL";
     case SIGABRT: return "SIGABRT";
     case SIGBUS: return "SIGBUS";
     case SIGFPE: return "SIGFPE";
-    case SIGSEGV: return "SIGSEGV";
+    case SIGILL: return "SIGILL";
     case SIGPIPE: return "SIGPIPE";
-#ifdef SIGSTKFLT
+    case SIGSEGV: return "SIGSEGV";
+#if defined(SIGSTKFLT)
     case SIGSTKFLT: return "SIGSTKFLT";
 #endif
     case SIGSTOP: return "SIGSTOP";
+    case SIGTRAP: return "SIGTRAP";
     default: return "?";
   }
 }
@@ -155,36 +172,38 @@
   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_fault_addr(log_t* log, pid_t tid, int sig) {
+static void dump_signal_info(log_t* log, pid_t tid, int signal, int si_code) {
   siginfo_t si;
-
   memset(&si, 0, sizeof(si));
-  if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si)){
+  if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si) == -1) {
     _LOG(log, SCOPE_AT_FAULT, "cannot get siginfo: %s\n", strerror(errno));
-  } else if (signal_has_address(sig)) {
-    _LOG(log, SCOPE_AT_FAULT, "signal %d (%s), code %d (%s), fault addr %" PRIPTR "\n",
-         sig, get_signame(sig), si.si_code, get_sigcode(sig, si.si_code),
-         reinterpret_cast<uintptr_t>(si.si_addr));
-  } else {
-    _LOG(log, SCOPE_AT_FAULT, "signal %d (%s), code %d (%s), fault addr --------\n",
-         sig, get_signame(sig), si.si_code, get_sigcode(sig, si.si_code));
+    return;
   }
+
+  // bionic has to re-raise some signals, which overwrites the si_code with SI_TKILL.
+  si.si_code = si_code;
+
+  char addr_desc[32]; // ", fault addr 0x1234"
+  if (signal_has_si_addr(signal)) {
+    snprintf(addr_desc, sizeof(addr_desc), "%p", si.si_addr);
+  } else {
+    snprintf(addr_desc, sizeof(addr_desc), "--------");
+  }
+
+  _LOG(log, SCOPE_AT_FAULT, "signal %d (%s), code %d (%s), fault addr %s\n",
+       signal, get_signame(signal), si.si_code, get_sigcode(signal, si.si_code), addr_desc);
 }
 
 static void dump_thread_info(log_t* log, pid_t pid, pid_t tid, int scope_flags) {
@@ -349,7 +368,7 @@
     _LOG(log, scope_flags, "cannot get siginfo for %d: %s\n", tid, strerror(errno));
     return;
   }
-  if (!signal_has_address(si.si_signo)) {
+  if (!signal_has_si_addr(si.si_signo)) {
     return;
   }
 
@@ -453,6 +472,8 @@
 // that don't match the specified pid, and writes them to the tombstone file.
 //
 // If "tail" is set, we only print the last few lines.
+static EventTagMap* g_eventTagMap = NULL;
+
 static void dump_log_file(log_t* log, pid_t pid, const char* filename,
   unsigned int tail) {
   bool first = true;
@@ -515,7 +536,28 @@
     if (!hdr_size) {
       hdr_size = sizeof(log_entry.entry_v1);
     }
-    char* msg = (char *)log_entry.buf + hdr_size;
+    char* msg = reinterpret_cast<char*>(log_entry.buf) + hdr_size;
+
+    char timeBuf[32];
+    time_t sec = static_cast<time_t>(entry->sec);
+    struct tm tmBuf;
+    struct tm* ptm;
+    ptm = localtime_r(&sec, &tmBuf);
+    strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);
+
+    if (log_entry.id() == LOG_ID_EVENTS) {
+      if (!g_eventTagMap) {
+        g_eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE);
+      }
+      AndroidLogEntry e;
+      char buf[512];
+      android_log_processBinaryLogBuffer(entry, &e, g_eventTagMap, buf, sizeof(buf));
+      _LOG(log, 0, "%s.%03d %5d %5d %c %-8s: %s\n",
+         timeBuf, entry->nsec / 1000000, entry->pid, entry->tid,
+         'I', e.tag, e.message);
+      continue;
+    }
+
     unsigned char prio = msg[0];
     char* tag = msg + 1;
     msg = tag + strlen(tag) + 1;
@@ -528,13 +570,6 @@
 
     char prioChar = (prio < strlen(kPrioChars) ? kPrioChars[prio] : '?');
 
-    char timeBuf[32];
-    time_t sec = static_cast<time_t>(entry->sec);
-    struct tm tmBuf;
-    struct tm* ptm;
-    ptm = localtime_r(&sec, &tmBuf);
-    strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);
-
     // Look for line breaks ('\n') and display each text line
     // on a separate line, prefixed with the header, like logcat does.
     do {
@@ -588,8 +623,9 @@
 }
 
 // Dumps all information about the specified pid to the tombstone.
-static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, uintptr_t abort_msg_address,
-                       bool dump_sibling_threads, int* total_sleep_time_usec) {
+static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, int si_code,
+                       uintptr_t abort_msg_address, bool dump_sibling_threads,
+                       int* total_sleep_time_usec) {
   // don't copy log messages to tombstone unless this is a dev device
   char value[PROPERTY_VALUE_MAX];
   property_get("ro.debuggable", value, "0");
@@ -607,11 +643,10 @@
 
   _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_fault_addr(log, tid, signal);
+    dump_signal_info(log, tid, signal, si_code);
   }
 
   UniquePtr<BacktraceMap> map(BacktraceMap::Create(pid));
@@ -725,37 +760,44 @@
   return amfd;
 }
 
-char* engrave_tombstone(
-    pid_t pid, pid_t tid, int signal, uintptr_t abort_msg_address, bool dump_sibling_threads,
-    bool quiet, bool* detach_failed, int* total_sleep_time_usec) {
+char* engrave_tombstone(pid_t pid, pid_t tid, int signal, int original_si_code,
+                        uintptr_t abort_msg_address, bool dump_sibling_threads, bool quiet,
+                        bool* detach_failed, int* total_sleep_time_usec) {
   if ((mkdir(TOMBSTONE_DIR, 0755) == -1) && (errno != EEXIST)) {
-      LOG("failed to create %s: %s\n", TOMBSTONE_DIR, strerror(errno));
+    LOG("failed to create %s: %s\n", TOMBSTONE_DIR, strerror(errno));
   }
 
   if (chown(TOMBSTONE_DIR, AID_SYSTEM, AID_SYSTEM) == -1) {
-      LOG("failed to change ownership of %s: %s\n", TOMBSTONE_DIR, strerror(errno));
+    LOG("failed to change ownership of %s: %s\n", TOMBSTONE_DIR, strerror(errno));
   }
 
-  if (selinux_android_restorecon(TOMBSTONE_DIR, 0) == -1) {
-    *detach_failed = false;
-    return NULL;
+  int fd = -1;
+  char* path = NULL;
+  if (selinux_android_restorecon(TOMBSTONE_DIR, 0) == 0) {
+    path = find_and_open_tombstone(&fd);
+  } else {
+    LOG("Failed to restore security context, not writing tombstone.\n");
   }
 
-  int fd;
-  char* path = find_and_open_tombstone(&fd);
-  if (!path) {
+  if (fd < 0 && quiet) {
+    LOG("Skipping tombstone write, nothing to do.\n");
     *detach_failed = false;
     return NULL;
   }
 
   log_t log;
   log.tfd = fd;
-  log.amfd = activity_manager_connect();
+  // Preserve amfd since it can be modified through the calls below without
+  // being closed.
+  int amfd = activity_manager_connect();
+  log.amfd = amfd;
   log.quiet = quiet;
-  *detach_failed = dump_crash(
-      &log, pid, tid, signal, abort_msg_address, dump_sibling_threads, total_sleep_time_usec);
+  *detach_failed = dump_crash(&log, pid, tid, signal, original_si_code, abort_msg_address,
+                              dump_sibling_threads, total_sleep_time_usec);
 
-  close(log.amfd);
+  // Either of these file descriptors can be -1, any error is ignored.
+  close(amfd);
   close(fd);
+
   return path;
 }
diff --git a/debuggerd/tombstone.h b/debuggerd/tombstone.h
index e9878bf..3574e84 100644
--- a/debuggerd/tombstone.h
+++ b/debuggerd/tombstone.h
@@ -23,7 +23,9 @@
 
 /* Creates a tombstone file and writes the crash dump to it.
  * Returns the path of the tombstone, which must be freed using free(). */
-char* engrave_tombstone(pid_t pid, pid_t tid, int signal, uintptr_t abort_msg_address,
-        bool dump_sibling_threads, bool quiet, bool* detach_failed, int* total_sleep_time_usec);
+char* engrave_tombstone(pid_t pid, pid_t tid, int signal, int original_si_code,
+                        uintptr_t abort_msg_address,
+                        bool dump_sibling_threads, bool quiet,
+                        bool* detach_failed, int* total_sleep_time_usec);
 
 #endif // _DEBUGGERD_TOMBSTONE_H
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/fastboot/Android.mk b/fastboot/Android.mk
index b9b3c92..73794a0 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -18,10 +18,10 @@
 
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/../mkbootimg \
   $(LOCAL_PATH)/../../extras/ext4_utils
-LOCAL_SRC_FILES := protocol.c engine.c bootimg.c fastboot.c util.c
+LOCAL_SRC_FILES := protocol.c engine.c bootimg.c fastboot.c util.c fs.c
 LOCAL_MODULE := fastboot
 LOCAL_MODULE_TAGS := debug
-LOCAL_CFLAGS += -std=gnu99
+LOCAL_CFLAGS += -std=gnu99 -Werror
 
 ifeq ($(HOST_OS),linux)
   LOCAL_SRC_FILES += usb_linux.c util_linux.c
@@ -72,6 +72,7 @@
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := usbtest.c usb_linux.c util.c
 LOCAL_MODULE := usbtest
+LOCAL_CFLAGS := -Werror
 include $(BUILD_HOST_EXECUTABLE)
 endif
 
diff --git a/fastboot/engine.c b/fastboot/engine.c
index 972c4ed..2f90e41 100644
--- a/fastboot/engine.c
+++ b/fastboot/engine.c
@@ -27,13 +27,13 @@
  */
 
 #include "fastboot.h"
-#include "make_ext4fs.h"
+#include "fs.h"
 
 #include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <stdarg.h>
 #include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -45,15 +45,18 @@
 #include <sys/mman.h>
 #endif
 
+#ifndef __unused
+#define __unused __attribute__((__unused__))
+#endif
+
 #define ARRAY_SIZE(x)           (sizeof(x)/sizeof(x[0]))
 
 #define OP_DOWNLOAD   1
 #define OP_COMMAND    2
 #define OP_QUERY      3
 #define OP_NOTICE     4
-#define OP_FORMAT     5
-#define OP_DOWNLOAD_SPARSE 6
-#define OP_WAIT_FOR_DISCONNECT 7
+#define OP_DOWNLOAD_SPARSE 5
+#define OP_WAIT_FOR_DISCONNECT 6
 
 typedef struct Action Action;
 
@@ -79,14 +82,7 @@
 static Action *action_last = 0;
 
 
-struct image_data {
-    long long partition_size;
-    long long image_size; // real size of image file
-    void *buffer;
-};
 
-void generate_ext4_image(struct image_data *image);
-void cleanup_image(struct image_data *image);
 
 int fb_getvar(struct usb_handle *usb, char *response, const char *fmt, ...)
 {
@@ -102,24 +98,6 @@
     return fb_command_response(usb, cmd, response);
 }
 
-struct generator {
-    char *fs_type;
-
-    /* generate image and return it as image->buffer.
-     * size of the buffer returned as image->image_size.
-     *
-     * image->partition_size specifies what is the size of the
-     * file partition we generate image for.
-     */
-    void (*generate)(struct image_data *image);
-
-    /* it cleans the buffer allocated during image creation.
-     * this function probably does free() or munmap().
-     */
-    void (*cleanup)(struct image_data *image);
-} generators[] = {
-    { "ext4", generate_ext4_image, cleanup_image }
-};
 
 /* Return true if this partition is supported by the fastboot format command.
  * It is also used to determine if we should first erase a partition before
@@ -128,30 +106,19 @@
  * Not all devices report the filesystem type, so don't report any errors,
  * just return false.
  */
-int fb_format_supported(usb_handle *usb, const char *partition)
+int fb_format_supported(usb_handle *usb, const char *partition, const char *type_override)
 {
-    char response[FB_RESPONSE_SZ+1];
-    struct generator *generator = NULL;
+    char fs_type[FB_RESPONSE_SZ + 1] = {0,};
     int status;
-    unsigned int i;
 
-    status = fb_getvar(usb, response, "partition-type:%s", partition);
+    if (type_override) {
+        return !!fs_get_generator(type_override);
+    }
+    status = fb_getvar(usb, fs_type, "partition-type:%s", partition);
     if (status) {
         return 0;
     }
-
-    for (i = 0; i < ARRAY_SIZE(generators); i++) {
-        if (!strncmp(generators[i].fs_type, response, FB_RESPONSE_SZ)) {
-            generator = &generators[i];
-            break;
-        }
-    }
-
-    if (generator) {
-        return 1;
-    }
-
-    return 0;
+    return !!fs_get_generator(fs_type);
 }
 
 static int cb_default(Action *a, int status, char *resp)
@@ -205,163 +172,6 @@
     a->msg = mkmsg("erasing '%s'", ptn);
 }
 
-/* Loads file content into buffer. Returns NULL on error. */
-static void *load_buffer(int fd, off_t size)
-{
-    void *buffer;
-
-#ifdef USE_MINGW
-    ssize_t count = 0;
-
-    // mmap is more efficient but mingw does not support it.
-    // In this case we read whole image into memory buffer.
-    buffer = malloc(size);
-    if (!buffer) {
-        perror("malloc");
-        return NULL;
-    }
-
-    lseek(fd, 0, SEEK_SET);
-    while(count < size) {
-        ssize_t actually_read = read(fd, (char*)buffer+count, size-count);
-
-        if (actually_read == 0) {
-            break;
-        }
-        if (actually_read < 0) {
-            if (errno == EINTR) {
-                continue;
-            }
-            perror("read");
-            free(buffer);
-            return NULL;
-        }
-
-        count += actually_read;
-    }
-#else
-    buffer = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
-    if (buffer == MAP_FAILED) {
-        perror("mmap");
-        return NULL;
-    }
-#endif
-
-    return buffer;
-}
-
-void cleanup_image(struct image_data *image)
-{
-#ifdef USE_MINGW
-    free(image->buffer);
-#else
-    munmap(image->buffer, image->image_size);
-#endif
-}
-
-void generate_ext4_image(struct image_data *image)
-{
-    int fd;
-    struct stat st;
-
-    fd = fileno(tmpfile());
-    make_ext4fs_sparse_fd(fd, image->partition_size, NULL, NULL);
-
-    fstat(fd, &st);
-    image->image_size = st.st_size;
-    image->buffer = load_buffer(fd, st.st_size);
-
-    close(fd);
-}
-
-int fb_format(Action *a, usb_handle *usb, int skip_if_not_supported)
-{
-    const char *partition = a->cmd;
-    char response[FB_RESPONSE_SZ+1];
-    int status = 0;
-    struct image_data image;
-    struct generator *generator = NULL;
-    int fd;
-    unsigned i;
-    char cmd[CMD_SIZE];
-
-    status = fb_getvar(usb, response, "partition-type:%s", partition);
-    if (status) {
-        if (skip_if_not_supported) {
-            fprintf(stderr,
-                    "Erase successful, but not automatically formatting.\n");
-            fprintf(stderr,
-                    "Can't determine partition type.\n");
-            return 0;
-        }
-        fprintf(stderr,"FAILED (%s)\n", fb_get_error());
-        return status;
-    }
-
-    for (i = 0; i < ARRAY_SIZE(generators); i++) {
-        if (!strncmp(generators[i].fs_type, response, FB_RESPONSE_SZ)) {
-            generator = &generators[i];
-            break;
-        }
-    }
-    if (!generator) {
-        if (skip_if_not_supported) {
-            fprintf(stderr,
-                    "Erase successful, but not automatically formatting.\n");
-            fprintf(stderr,
-                    "File system type %s not supported.\n", response);
-            return 0;
-        }
-        fprintf(stderr,"Formatting is not supported for filesystem with type '%s'.\n",
-                response);
-        return -1;
-    }
-
-    status = fb_getvar(usb, response, "partition-size:%s", partition);
-    if (status) {
-        if (skip_if_not_supported) {
-            fprintf(stderr,
-                    "Erase successful, but not automatically formatting.\n");
-            fprintf(stderr, "Unable to get partition size\n.");
-            return 0;
-        }
-        fprintf(stderr,"FAILED (%s)\n", fb_get_error());
-        return status;
-    }
-    image.partition_size = strtoll(response, (char **)NULL, 16);
-
-    generator->generate(&image);
-    if (!image.buffer) {
-        fprintf(stderr,"Cannot generate image.\n");
-        return -1;
-    }
-
-    // Following piece of code is similar to fb_queue_flash() but executes
-    // actions directly without queuing
-    fprintf(stderr, "sending '%s' (%lli KB)...\n", partition, image.image_size/1024);
-    status = fb_download_data(usb, image.buffer, image.image_size);
-    if (status) goto cleanup;
-
-    fprintf(stderr, "writing '%s'...\n", partition);
-    snprintf(cmd, sizeof(cmd), "flash:%s", partition);
-    status = fb_command(usb, cmd);
-    if (status) goto cleanup;
-
-cleanup:
-    generator->cleanup(&image);
-
-    return status;
-}
-
-void fb_queue_format(const char *partition, int skip_if_not_supported)
-{
-    Action *a;
-
-    a = queue_action(OP_FORMAT, partition);
-    a->data = (void*)skip_if_not_supported;
-    a->msg = mkmsg("formatting '%s' partition", partition);
-}
-
 void fb_queue_flash(const char *ptn, void *data, unsigned sz)
 {
     Action *a;
@@ -390,9 +200,7 @@
 
 static int match(char *str, const char **value, unsigned count)
 {
-    const char *val;
     unsigned n;
-    int len;
 
     for (n = 0; n < count; n++) {
         const char *val = value[n];
@@ -518,7 +326,7 @@
     a->func = cb_save;
 }
 
-static int cb_do_nothing(Action *a, int status, char *resp)
+static int cb_do_nothing(Action *a __unused, int status __unused, char *resp __unused)
 {
     fprintf(stderr,"\n");
     return 0;
@@ -589,10 +397,6 @@
             if (status) break;
         } else if (a->op == OP_NOTICE) {
             fprintf(stderr,"%s\n",(char*)a->data);
-        } else if (a->op == OP_FORMAT) {
-            status = fb_format(a, usb, (int)a->data);
-            status = a->func(a, status, status ? fb_get_error() : "");
-            if (status) break;
         } else if (a->op == OP_DOWNLOAD_SPARSE) {
             status = fb_download_data_sparse(usb, a->data);
             status = a->func(a, status, status ? fb_get_error() : "");
diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c
index 73a6e56..9c04c21 100644
--- a/fastboot/fastboot.c
+++ b/fastboot/fastboot.c
@@ -28,27 +28,28 @@
 
 #define _LARGEFILE64_SOURCE
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <string.h>
+#include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <unistd.h>
-#include <limits.h>
-#include <ctype.h>
 #include <getopt.h>
-
+#include <inttypes.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/types.h>
-#include <sys/stat.h>
+#include <unistd.h>
 
 #include <bootimg.h>
 #include <sparse/sparse.h>
 #include <zipfile/zipfile.h>
 
 #include "fastboot.h"
+#include "fs.h"
 
 #ifndef O_BINARY
 #define O_BINARY 0
@@ -70,7 +71,6 @@
 static const char *serial = 0;
 static const char *product = 0;
 static const char *cmdline = 0;
-static int wipe_data = 0;
 static unsigned short vendor_id = 0;
 static int long_listing = 0;
 static int64_t sparse_limit = -1;
@@ -99,10 +99,11 @@
     char sig_name[13];
     char part_name[9];
     bool is_optional;
-} images[3] = {
+} images[4] = {
     {"boot.img", "boot.sig", "boot", false},
     {"recovery.img", "recovery.sig", "recovery", true},
     {"system.img", "system.sig", "system", false},
+    {"tos.img", "tos.sig", "tos", true},
 };
 
 void get_my_path(char *path);
@@ -119,6 +120,8 @@
         fn = "recovery.img";
     } else if(!strcmp(item,"system")) {
         fn = "system.img";
+    } else if(!strcmp(item,"tos")) {
+        fn = "tos.img";
     } else if(!strcmp(item,"userdata")) {
         fn = "userdata.img";
     } else if(!strcmp(item,"cache")) {
@@ -265,7 +268,7 @@
             announce = 0;
             fprintf(stderr,"< waiting for device >\n");
         }
-        sleep(1);
+        usleep(1000);
     }
 }
 
@@ -284,10 +287,13 @@
             "\n"
             "commands:\n"
             "  update <filename>                        reflash device from update.zip\n"
-            "  flashall                                 flash boot + recovery + system\n"
+            "  flashall                                 flash boot, system, and if found,\n"
+            "                                           recovery, tos\n"
             "  flash <partition> [ <filename> ]         write a file to a flash partition\n"
             "  erase <partition>                        erase a flash partition\n"
-            "  format <partition>                       format a flash partition \n"
+            "  format[:[<fs type>][:[<size>]] <partition> format a flash partition.\n"
+            "                                           Can override the fs type and/or\n"
+            "                                           size the bootloader reports.\n"
             "  getvar <variable>                        display a bootloader variable\n"
             "  boot <kernel> [ <ramdisk> ]              download and boot kernel\n"
             "  flash:raw boot <kernel> [ <ramdisk> ]    create bootimage and flash it\n"
@@ -308,10 +314,12 @@
             "  -p <product>                             specify product name\n"
             "  -c <cmdline>                             override kernel commandline\n"
             "  -i <vendor id>                           specify a custom USB vendor id\n"
-            "  -b <base_addr>                           specify a custom kernel base address. default: 0x10000000\n"
-            "  -n <page size>                           specify the nand page size. default: 2048\n"
-            "  -S <size>[K|M|G]                         automatically sparse files greater than\n"
-            "                                           size.  0 to disable\n"
+            "  -b <base_addr>                           specify a custom kernel base address.\n"
+            "                                           default: 0x10000000\n"
+            "  -n <page size>                           specify the nand page size.\n"
+            "                                           default: 2048\n"
+            "  -S <size>[K|M|G]                         automatically sparse files greater\n"
+            "                                           than size.  0 to disable\n"
         );
 }
 
@@ -418,7 +426,7 @@
         return -1;
     }
 
-    if (write(fd, data, sz) != sz) {
+    if (write(fd, data, sz) != (ssize_t)sz) {
         fd = -1;
     }
 
@@ -569,7 +577,7 @@
     if (!status) {
         limit = strtoul(response, NULL, 0);
         if (limit > 0) {
-            fprintf(stderr, "target reported max download size of %lld bytes\n",
+            fprintf(stderr, "target reported max download size of %" PRId64 " bytes\n",
                     limit);
         }
     }
@@ -612,7 +620,7 @@
     /* The function fb_format_supported() currently returns the value
      * we want, so just call it.
      */
-     return fb_format_supported(usb, part);
+     return fb_format_supported(usb, part, NULL);
 }
 
 static int load_buf_fd(usb_handle *usb, int fd,
@@ -622,10 +630,13 @@
     void *data;
     int64_t limit;
 
+
     sz64 = file_size(fd);
     if (sz64 < 0) {
         return -1;
     }
+
+    lseek(fd, 0, SEEK_SET);
     limit = get_sparse_limit(usb, sz64);
     if (limit) {
         struct sparse_file **s = load_sparse_files(fd, limit);
@@ -653,7 +664,7 @@
 
     fd = open(fname, O_RDONLY | O_BINARY);
     if (fd < 0) {
-        die("cannot open '%s'\n", fname);
+        return -1;
     }
 
     return load_buf_fd(usb, fd, buf);
@@ -709,7 +720,7 @@
     int fd;
     int rc;
     struct fastboot_buffer buf;
-    int i;
+    size_t i;
 
     queue_info_dump();
 
@@ -783,7 +794,7 @@
     void *data;
     unsigned sz;
     struct fastboot_buffer buf;
-    int i;
+    size_t i;
 
     queue_info_dump();
 
@@ -815,7 +826,6 @@
 
 int do_oem_command(int argc, char **argv)
 {
-    int i;
     char command[256];
     if (argc <= 1) return 0;
 
@@ -872,6 +882,92 @@
     return num;
 }
 
+void fb_perform_format(const char *partition, int skip_if_not_supported,
+                       const char *type_override, const char *size_override)
+{
+    char pTypeBuff[FB_RESPONSE_SZ + 1], pSizeBuff[FB_RESPONSE_SZ + 1];
+    char *pType = pTypeBuff;
+    char *pSize = pSizeBuff;
+    unsigned int limit = INT_MAX;
+    struct fastboot_buffer buf;
+    const char *errMsg = NULL;
+    const struct fs_generator *gen;
+    uint64_t pSz;
+    int status;
+    int fd;
+
+    if (target_sparse_limit > 0 && target_sparse_limit < limit)
+        limit = target_sparse_limit;
+    if (sparse_limit > 0 && sparse_limit < limit)
+        limit = sparse_limit;
+
+    status = fb_getvar(usb, pType, "partition-type:%s", partition);
+    if (status) {
+        errMsg = "Can't determine partition type.\n";
+        goto failed;
+    }
+    if (type_override) {
+        if (strcmp(type_override, pType)) {
+            fprintf(stderr,
+                    "Warning: %s type is %s, but %s was requested for formating.\n",
+                    partition, pType, type_override);
+        }
+        pType = (char *)type_override;
+    }
+
+    status = fb_getvar(usb, pSize, "partition-size:%s", partition);
+    if (status) {
+        errMsg = "Unable to get partition size\n";
+        goto failed;
+    }
+    if (size_override) {
+        if (strcmp(size_override, pSize)) {
+            fprintf(stderr,
+                    "Warning: %s size is %s, but %s was requested for formating.\n",
+                    partition, pSize, size_override);
+        }
+        pSize = (char *)size_override;
+    }
+
+    gen = fs_get_generator(pType);
+    if (!gen) {
+        if (skip_if_not_supported) {
+            fprintf(stderr, "Erase successful, but not automatically formatting.\n");
+            fprintf(stderr, "File system type %s not supported.\n", pType);
+            return;
+        }
+        fprintf(stderr, "Formatting is not supported for filesystem with type '%s'.\n", pType);
+        return;
+    }
+
+    pSz = strtoll(pSize, (char **)NULL, 16);
+
+    fd = fileno(tmpfile());
+    if (fs_generator_generate(gen, fd, pSz)) {
+        close(fd);
+        fprintf(stderr, "Cannot generate image.\n");
+        return;
+    }
+
+    if (load_buf_fd(usb, fd, &buf)) {
+        fprintf(stderr, "Cannot read image.\n");
+        close(fd);
+        return;
+    }
+    flash_buf(partition, &buf);
+
+    return;
+
+
+failed:
+    if (skip_if_not_supported) {
+        fprintf(stderr, "Erase successful, but not automatically formatting.\n");
+        if (errMsg)
+            fprintf(stderr, "%s", errMsg);
+    }
+    fprintf(stderr,"FAILED (%s)\n", fb_get_error());
+}
+
 int main(int argc, char **argv)
 {
     int wants_wipe = 0;
@@ -882,13 +978,13 @@
     unsigned sz;
     int status;
     int c;
-    int r;
 
     const struct option longopts[] = {
         {"base", required_argument, 0, 'b'},
         {"kernel_offset", required_argument, 0, 'k'},
         {"page_size", required_argument, 0, 'n'},
         {"ramdisk_offset", required_argument, 0, 'r'},
+        {"tags_offset", required_argument, 0, 't'},
         {"help", 0, 0, 'h'},
         {0, 0, 0, 0}
     };
@@ -896,8 +992,7 @@
     serial = getenv("ANDROID_SERIAL");
 
     while (1) {
-        int option_index = 0;
-        c = getopt_long(argc, argv, "wub:k:n:r:s:S:lp:c:i:m:h", longopts, NULL);
+        c = getopt_long(argc, argv, "wub:k:n:r:t:s:S:lp:c:i:m:h", longopts, NULL);
         if (c < 0) {
             break;
         }
@@ -938,6 +1033,9 @@
         case 'r':
             ramdisk_offset = strtoul(optarg, 0, 16);
             break;
+        case 't':
+            tags_offset = strtoul(optarg, 0, 16);
+            break;
         case 's':
             serial = optarg;
             break;
@@ -989,18 +1087,42 @@
         } else if(!strcmp(*argv, "erase")) {
             require(2);
 
-            if (fb_format_supported(usb, argv[1])) {
+            if (fb_format_supported(usb, argv[1], NULL)) {
                 fprintf(stderr, "******** Did you mean to fastboot format this partition?\n");
             }
 
             fb_queue_erase(argv[1]);
             skip(2);
-        } else if(!strcmp(*argv, "format")) {
+        } else if(!strncmp(*argv, "format", strlen("format"))) {
+            char *overrides;
+            char *type_override = NULL;
+            char *size_override = NULL;
             require(2);
+            /*
+             * Parsing for: "format[:[type][:[size]]]"
+             * Some valid things:
+             *  - select ontly the size, and leave default fs type:
+             *    format::0x4000000 userdata
+             *  - default fs type and size:
+             *    format userdata
+             *    format:: userdata
+             */
+            overrides = strchr(*argv, ':');
+            if (overrides) {
+                overrides++;
+                size_override = strchr(overrides, ':');
+                if (size_override) {
+                    size_override[0] = '\0';
+                    size_override++;
+                }
+                type_override = overrides;
+            }
+            if (type_override && !type_override[0]) type_override = NULL;
+            if (size_override && !size_override[0]) size_override = NULL;
             if (erase_first && needs_erase(argv[1])) {
                 fb_queue_erase(argv[1]);
             }
-            fb_queue_format(argv[1], 0);
+            fb_perform_format(argv[1], 0, type_override, size_override);
             skip(2);
         } else if(!strcmp(*argv, "signature")) {
             require(2);
@@ -1088,9 +1210,9 @@
 
     if (wants_wipe) {
         fb_queue_erase("userdata");
-        fb_queue_format("userdata", 1);
+        fb_perform_format("userdata", 1, NULL, NULL);
         fb_queue_erase("cache");
-        fb_queue_format("cache", 1);
+        fb_perform_format("cache", 1, NULL, NULL);
     }
     if (wants_reboot) {
         fb_queue_reboot();
diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h
index 976c397..fc5d4f4 100644
--- a/fastboot/fastboot.h
+++ b/fastboot/fastboot.h
@@ -45,11 +45,11 @@
 
 /* engine.c - high level command queue engine */
 int fb_getvar(struct usb_handle *usb, char *response, const char *fmt, ...);
-int fb_format_supported(usb_handle *usb, const char *partition);
+int fb_format_supported(usb_handle *usb, const char *partition, const char *type_override);
 void fb_queue_flash(const char *ptn, void *data, unsigned sz);
 void fb_queue_flash_sparse(const char *ptn, struct sparse_file *s, unsigned sz);
 void fb_queue_erase(const char *ptn);
-void fb_queue_format(const char *ptn, int skip_if_not_supported);
+void fb_queue_format(const char *ptn, int skip_if_not_supported, unsigned int max_chunk_sz);
 void fb_queue_require(const char *prod, const char *var, int invert,
         unsigned nvalues, const char **value);
 void fb_queue_display(const char *var, const char *prettyname);
diff --git a/fastboot/fs.c b/fastboot/fs.c
new file mode 100644
index 0000000..cd4b880
--- /dev/null
+++ b/fastboot/fs.c
@@ -0,0 +1,56 @@
+#include "fastboot.h"
+#include "make_ext4fs.h"
+#include "fs.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sparse/sparse.h>
+#include <unistd.h>
+
+#ifdef USE_MINGW
+#include <fcntl.h>
+#else
+#include <sys/mman.h>
+#endif
+
+
+
+static int generate_ext4_image(int fd, long long partSize)
+{
+    make_ext4fs_sparse_fd(fd, partSize, NULL, NULL);
+
+    return 0;
+}
+
+static const struct fs_generator {
+
+    char *fs_type;  //must match what fastboot reports for partition type
+    int (*generate)(int fd, long long partSize); //returns 0 or error value
+
+} generators[] = {
+
+    { "ext4", generate_ext4_image}
+
+};
+
+const struct fs_generator* fs_get_generator(const char *fs_type)
+{
+    unsigned i;
+
+    for (i = 0; i < sizeof(generators) / sizeof(*generators); i++)
+        if (!strcmp(generators[i].fs_type, fs_type))
+            return generators + i;
+
+    return NULL;
+}
+
+int fs_generator_generate(const struct fs_generator* gen, int tmpFileNo, long long partSize)
+{
+    return gen->generate(tmpFileNo, partSize);
+}
diff --git a/fastboot/fs.h b/fastboot/fs.h
new file mode 100644
index 0000000..8388629
--- /dev/null
+++ b/fastboot/fs.h
@@ -0,0 +1,12 @@
+#ifndef _FS_H_
+#define _FH_H_
+
+#include <stdint.h>
+
+struct fs_generator;
+
+const struct fs_generator* fs_get_generator(const char *fs_type);
+int fs_generator_generate(const struct fs_generator* gen, int tmpFileNo, long long partSize);
+
+#endif
+
diff --git a/fastboot/protocol.c b/fastboot/protocol.c
index a0e0fd4..84e9837 100644
--- a/fastboot/protocol.c
+++ b/fastboot/protocol.c
@@ -110,7 +110,6 @@
                           char *response)
 {
     int cmdsize = strlen(cmd);
-    int r;
 
     if(response) {
         response[0] = 0;
@@ -189,8 +188,6 @@
 static int _command_send_no_data(usb_handle *usb, const char *cmd,
                                  char *response)
 {
-    int r;
-
     return _command_start(usb, cmd, 0, response);
 }
 
diff --git a/fastboot/usb_linux.c b/fastboot/usb_linux.c
index f2ce226..a45f9f8 100644
--- a/fastboot/usb_linux.c
+++ b/fastboot/usb_linux.c
@@ -125,9 +125,6 @@
     unsigned i;
     unsigned e;
     
-    struct stat st;
-    int result;
-
     if(check(ptr, len, USB_DT_DEVICE, USB_DT_DEVICE_SIZE))
         return -1;
     dev = (void*) ptr;
diff --git a/fastboot/usb_windows.c b/fastboot/usb_windows.c
index 07f7be2..0d13863 100644
--- a/fastboot/usb_windows.c
+++ b/fastboot/usb_windows.c
@@ -152,7 +152,7 @@
 }
 
 int usb_write(usb_handle* handle, const void* data, int len) {
-    unsigned long time_out = 500 + len * 8;
+    unsigned long time_out = 5000;
     unsigned long written = 0;
     unsigned count = 0;
     int ret;
@@ -178,7 +178,7 @@
 
             count += written;
             len -= written;
-            data += written;
+            data = (const char *)data + written;
 
             if (len == 0)
                 return count;
@@ -194,7 +194,7 @@
 }
 
 int usb_read(usb_handle *handle, void* data, int len) {
-    unsigned long time_out = 500 + len * 8;
+    unsigned long time_out = 0;
     unsigned long read = 0;
     int ret;
 
@@ -212,7 +212,7 @@
             DBG("usb_read got: %ld, expected: %d, errno: %d\n", read, xfer, errno);
             if (ret) {
                 return read;
-            } else if (errno != ERROR_SEM_TIMEOUT) {
+            } else {
                 // assume ERROR_INVALID_HANDLE indicates we are disconnected
                 if (errno == ERROR_INVALID_HANDLE)
                     usb_kick(handle);
diff --git a/fastboot/usbtest.c b/fastboot/usbtest.c
index b8fb9e2..e6e2b37 100644
--- a/fastboot/usbtest.c
+++ b/fastboot/usbtest.c
@@ -88,14 +88,14 @@
 
 int test_null(usb_handle *usb)
 {
-    int i;
+    unsigned i;
     unsigned char buf[4096];
     memset(buf, 0xee, 4096);
     long long t0, t1;
 
     t0 = NOW();
     for(i = 0; i < arg_count; i++) {
-        if(usb_write(usb, buf, arg_size) != arg_size) {
+        if(usb_write(usb, buf, arg_size) != (int)arg_size) {
             fprintf(stderr,"write failed (%s)\n", strerror(errno));
             return -1;
         }
@@ -107,13 +107,13 @@
 
 int test_zero(usb_handle *usb)
 {
-    int i;
+    unsigned i;
     unsigned char buf[4096];
     long long t0, t1;
 
     t0 = NOW();
     for(i = 0; i < arg_count; i++) {
-        if(usb_read(usb, buf, arg_size) != arg_size) {
+        if(usb_read(usb, buf, arg_size) != (int)arg_size) {
             fprintf(stderr,"read failed (%s)\n", strerror(errno));
             return -1;
         }
@@ -130,11 +130,11 @@
     int (*test)(usb_handle *usb);
     const char *help;
 } tests[] = {
-    { "list", printifc,   0,         "list interfaces" },
+    { "list", printifc,   NULL,      "list interfaces" },
     { "send", match_null, test_null, "send to null interface" },
     { "recv", match_zero, test_zero, "recv from zero interface" },
-    { "loop", match_loop, 0,         "exercise loopback interface" },
-    {},
+    { "loop", match_loop, NULL,      "exercise loopback interface" },
+    { NULL, NULL, NULL, NULL },
 };
 
 int usage(void)
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/fs_mgr/Android.mk b/fs_mgr/Android.mk
index 165ebd4..7cffc37 100644
--- a/fs_mgr/Android.mk
+++ b/fs_mgr/Android.mk
@@ -11,6 +11,7 @@
 LOCAL_STATIC_LIBRARIES := liblogwrap libmincrypt libext4_utils_static
 LOCAL_C_INCLUDES += system/extras/ext4_utils
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_CFLAGS := -Werror
 
 include $(BUILD_STATIC_LIBRARY)
 
@@ -31,5 +32,7 @@
 
 LOCAL_STATIC_LIBRARIES := libfs_mgr liblogwrap libcutils liblog libc libmincrypt libext4_utils_static
 
+LOCAL_CFLAGS := -Werror
+
 include $(BUILD_EXECUTABLE)
 
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index 45bbfdc..f86fc6a 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -162,7 +162,6 @@
         p = strtok_r(NULL, ",", &savep);
     }
 
-out:
     if (fs_options && fs_options[0]) {
         /* remove the last trailing comma from the list of options */
         fs_options[strlen(fs_options) - 1] = '\0';
@@ -181,7 +180,6 @@
     const char *delim = " \t";
     char *save_ptr, *p;
     struct fstab *fstab = NULL;
-    struct fstab_rec *recs;
     struct fs_mgr_flag_values flag_vals;
 #define FS_OPTIONS_LEN 1024
     char tmp_fs_options[FS_OPTIONS_LEN];
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index 40bc2ec..c9a2a9b 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -85,7 +85,6 @@
 
 static int verify_table(char *signature, char *table, int table_length)
 {
-    int fd;
     RSAPublicKey *key;
     uint8_t hash_buf[SHA_DIGEST_SIZE];
     int retval = -1;
diff --git a/gpttool/Android.mk b/gpttool/Android.mk
index b8f9844..64ad945 100644
--- a/gpttool/Android.mk
+++ b/gpttool/Android.mk
@@ -5,6 +5,7 @@
 
 LOCAL_SRC_FILES := gpttool.c
 LOCAL_STATIC_LIBRARIES := libz
+LOCAL_CFLAGS := -Werror
 
 LOCAL_MODULE := gpttool
 
diff --git a/gpttool/gpttool.c b/gpttool/gpttool.c
index d3f08fe..398362f 100644
--- a/gpttool/gpttool.c
+++ b/gpttool/gpttool.c
@@ -1,5 +1,4 @@
-/* system/core/gpttool/gpttool.c
-**
+/*
 ** Copyright 2011, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,18 +14,18 @@
 ** limitations under the License.
 */
 
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <string.h>
-#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 #include <zlib.h>
 
 #include <linux/fs.h>
 
-#include <sys/stat.h>
-
 typedef unsigned char u8;
 typedef unsigned short u16;
 typedef unsigned int u32;
@@ -252,11 +251,9 @@
 int main(int argc, char **argv)
 {
 	struct ptable ptbl;
-	struct efi_entry *entry;
 	struct efi_header *hdr = &ptbl.header;
-	struct stat s;
 	u32 n;
-	u64 sz, blk;
+	u64 sz;
 	int fd;
 	const char *device;
 	int real_disk = 0;
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/Backtrace.h b/include/backtrace/Backtrace.h
index 3c3a482..e07d322 100644
--- a/include/backtrace/Backtrace.h
+++ b/include/backtrace/Backtrace.h
@@ -47,6 +47,14 @@
 // Forward declarations.
 class BacktraceImpl;
 
+#if defined(__APPLE__)
+struct __darwin_ucontext;
+typedef __darwin_ucontext ucontext_t;
+#else
+struct ucontext;
+typedef ucontext ucontext_t;
+#endif
+
 class Backtrace {
 public:
   // Create the correct Backtrace object based on what is to be unwound.
@@ -64,7 +72,7 @@
   virtual ~Backtrace();
 
   // Get the current stack trace and store in the backtrace_ structure.
-  virtual bool Unwind(size_t num_ignore_frames);
+  virtual bool Unwind(size_t num_ignore_frames, ucontext_t* context = NULL);
 
   // Get the function name and offset into the function given the pc.
   // If the string is empty, then no valid function name was found.
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/corkscrew/backtrace.h b/include/corkscrew/backtrace.h
deleted file mode 100644
index 556ad04..0000000
--- a/include/corkscrew/backtrace.h
+++ /dev/null
@@ -1,115 +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.
- */
-
-/* A stack unwinder. */
-
-#ifndef _CORKSCREW_BACKTRACE_H
-#define _CORKSCREW_BACKTRACE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/types.h>
-#include <corkscrew/ptrace.h>
-#include <corkscrew/map_info.h>
-#include <corkscrew/symbol_table.h>
-
-/*
- * Describes a single frame of a backtrace.
- */
-typedef struct {
-    uintptr_t absolute_pc;     /* absolute PC offset */
-    uintptr_t stack_top;       /* top of stack for this frame */
-    size_t stack_size;         /* size of this stack frame */
-} backtrace_frame_t;
-
-/*
- * Describes the symbols associated with a backtrace frame.
- */
-typedef struct {
-    uintptr_t relative_pc;       /* relative frame PC offset from the start of the library,
-                                    or the absolute PC if the library is unknown */
-    uintptr_t relative_symbol_addr; /* relative offset of the symbol from the start of the
-                                    library or 0 if the library is unknown */
-    char* map_name;              /* executable or library name, or NULL if unknown */
-    char* symbol_name;           /* symbol name, or NULL if unknown */
-    char* demangled_name;        /* demangled symbol name, or NULL if unknown */
-} backtrace_symbol_t;
-
-/*
- * Unwinds the call stack for the current thread of execution.
- * Populates the backtrace array with the program counters from the call stack.
- * Returns the number of frames collected, or -1 if an error occurred.
- */
-ssize_t unwind_backtrace(backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth);
-
-/*
- * Unwinds the call stack for a thread within this process.
- * Populates the backtrace array with the program counters from the call stack.
- * Returns the number of frames collected, or -1 if an error occurred.
- *
- * The task is briefly suspended while the backtrace is being collected.
- */
-ssize_t unwind_backtrace_thread(pid_t tid, backtrace_frame_t* backtrace,
-        size_t ignore_depth, size_t max_depth);
-
-/*
- * Unwinds the call stack of a task within a remote process using ptrace().
- * Populates the backtrace array with the program counters from the call stack.
- * Returns the number of frames collected, or -1 if an error occurred.
- */
-ssize_t unwind_backtrace_ptrace(pid_t tid, const ptrace_context_t* context,
-        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth);
-
-/*
- * Gets the symbols for each frame of a backtrace.
- * The symbols array must be big enough to hold one symbol record per frame.
- * The symbols must later be freed using free_backtrace_symbols.
- */
-void get_backtrace_symbols(const backtrace_frame_t* backtrace, size_t frames,
-        backtrace_symbol_t* backtrace_symbols);
-
-/*
- * Gets the symbols for each frame of a backtrace from a remote process.
- * The symbols array must be big enough to hold one symbol record per frame.
- * The symbols must later be freed using free_backtrace_symbols.
- */
-void get_backtrace_symbols_ptrace(const ptrace_context_t* context,
-        const backtrace_frame_t* backtrace, size_t frames,
-        backtrace_symbol_t* backtrace_symbols);
-
-/*
- * Frees the storage associated with backtrace symbols.
- */
-void free_backtrace_symbols(backtrace_symbol_t* backtrace_symbols, size_t frames);
-
-enum {
-    // A hint for how big to make the line buffer for format_backtrace_line
-    MAX_BACKTRACE_LINE_LENGTH = 800,
-};
-
-/**
- * Formats a line from a backtrace as a zero-terminated string into the specified buffer.
- */
-void format_backtrace_line(unsigned frameNumber, const backtrace_frame_t* frame,
-        const backtrace_symbol_t* symbol, char* buffer, size_t bufferSize);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _CORKSCREW_BACKTRACE_H
diff --git a/include/corkscrew/demangle.h b/include/corkscrew/demangle.h
deleted file mode 100644
index 04b0225..0000000
--- a/include/corkscrew/demangle.h
+++ /dev/null
@@ -1,42 +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.
- */
-
-/* C++ symbol name demangling. */
-
-#ifndef _CORKSCREW_DEMANGLE_H
-#define _CORKSCREW_DEMANGLE_H
-
-#include <sys/types.h>
-#include <stdbool.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Demangles a C++ symbol name.
- * If name is NULL or if the name cannot be demangled, returns NULL.
- * Otherwise, returns a newly allocated string that contains the demangled name.
- *
- * The caller must free the returned string using free().
- */
-char* demangle_symbol_name(const char* name);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _CORKSCREW_DEMANGLE_H
diff --git a/include/corkscrew/map_info.h b/include/corkscrew/map_info.h
deleted file mode 100644
index 14bfad6..0000000
--- a/include/corkscrew/map_info.h
+++ /dev/null
@@ -1,74 +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.
- */
-
-/* Process memory map. */
-
-#ifndef _CORKSCREW_MAP_INFO_H
-#define _CORKSCREW_MAP_INFO_H
-
-#include <sys/types.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct map_info {
-    struct map_info* next;
-    uintptr_t start;
-    uintptr_t end;
-    bool is_readable;
-    bool is_writable;
-    bool is_executable;
-    void* data; // arbitrary data associated with the map by the user, initially NULL
-    char name[];
-} map_info_t;
-
-/* Loads memory map from /proc/<tid>/maps. */
-map_info_t* load_map_info_list(pid_t tid);
-
-/* Frees memory map. */
-void free_map_info_list(map_info_t* milist);
-
-/* Finds the memory map that contains the specified address. */
-const map_info_t* find_map_info(const map_info_t* milist, uintptr_t addr);
-
-/* Returns true if the addr is in a readable map. */
-bool is_readable_map(const map_info_t* milist, uintptr_t addr);
-/* Returns true if the addr is in a writable map. */
-bool is_writable_map(const map_info_t* milist, uintptr_t addr);
-/* Returns true if the addr is in an executable map. */
-bool is_executable_map(const map_info_t* milist, uintptr_t addr);
-
-/* Acquires a reference to the memory map for this process.
- * The result is cached and refreshed automatically.
- * Make sure to release the map info when done. */
-map_info_t* acquire_my_map_info_list();
-
-/* Releases a reference to the map info for this process that was
- * previous acquired using acquire_my_map_info_list(). */
-void release_my_map_info_list(map_info_t* milist);
-
-/* Flushes the cached memory map so the next call to
- * acquire_my_map_info_list() gets fresh data. */
-void flush_my_map_info_list();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _CORKSCREW_MAP_INFO_H
diff --git a/include/corkscrew/ptrace.h b/include/corkscrew/ptrace.h
deleted file mode 100644
index 76276d8..0000000
--- a/include/corkscrew/ptrace.h
+++ /dev/null
@@ -1,134 +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.
- */
-
-/* Useful ptrace() utility functions. */
-
-#ifndef _CORKSCREW_PTRACE_H
-#define _CORKSCREW_PTRACE_H
-
-#include <corkscrew/map_info.h>
-#include <corkscrew/symbol_table.h>
-
-#include <sys/types.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Stores information about a process that is used for several different
- * ptrace() based operations. */
-typedef struct {
-    map_info_t* map_info_list;
-} ptrace_context_t;
-
-/* Describes how to access memory from a process. */
-typedef struct {
-    pid_t tid;
-    const map_info_t* map_info_list;
-} memory_t;
-
-#if __i386__
-/* ptrace() register context. */
-typedef struct pt_regs_x86 {
-    uint32_t ebx;
-    uint32_t ecx;
-    uint32_t edx;
-    uint32_t esi;
-    uint32_t edi;
-    uint32_t ebp;
-    uint32_t eax;
-    uint32_t xds;
-    uint32_t xes;
-    uint32_t xfs;
-    uint32_t xgs;
-    uint32_t orig_eax;
-    uint32_t eip;
-    uint32_t xcs;
-    uint32_t eflags;
-    uint32_t esp;
-    uint32_t xss;
-} pt_regs_x86_t;
-#endif
-
-#if __mips__
-/* ptrace() GET_REGS context. */
-typedef struct pt_regs_mips {
-    uint64_t regs[32];
-    uint64_t lo;
-    uint64_t hi;
-    uint64_t cp0_epc;
-    uint64_t cp0_badvaddr;
-    uint64_t cp0_status;
-    uint64_t cp0_cause;
-} pt_regs_mips_t;
-#endif
-
-/*
- * Initializes a memory structure for accessing memory from this process.
- */
-void init_memory(memory_t* memory, const map_info_t* map_info_list);
-
-/*
- * Initializes a memory structure for accessing memory from another process
- * using ptrace().
- */
-void init_memory_ptrace(memory_t* memory, pid_t tid);
-
-/*
- * Reads a word of memory safely.
- * If the memory is local, ensures that the address is readable before dereferencing it.
- * Returns false and a value of 0xffffffff if the word could not be read.
- */
-bool try_get_word(const memory_t* memory, uintptr_t ptr, uint32_t* out_value);
-
-/*
- * Reads a word of memory safely using ptrace().
- * Returns false and a value of 0xffffffff if the word could not be read.
- */
-bool try_get_word_ptrace(pid_t tid, uintptr_t ptr, uint32_t* out_value);
-
-/*
- * Loads information needed for examining a remote process using ptrace().
- * The caller must already have successfully attached to the process
- * using ptrace().
- *
- * The context can be used for any threads belonging to that process
- * assuming ptrace() is attached to them before performing the actual
- * unwinding.  The context can continue to be used to decode backtraces
- * even after ptrace() has been detached from the process.
- */
-ptrace_context_t* load_ptrace_context(pid_t pid);
-
-/*
- * Frees a ptrace context.
- */
-void free_ptrace_context(ptrace_context_t* context);
-
-/*
- * Finds a symbol using ptrace.
- * Returns the containing map and information about the symbol, or
- * NULL if one or the other is not available.
- */
-void find_symbol_ptrace(const ptrace_context_t* context,
-        uintptr_t addr, const map_info_t** out_map_info, const symbol_t** out_symbol);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _CORKSCREW_PTRACE_H
diff --git a/include/corkscrew/symbol_table.h b/include/corkscrew/symbol_table.h
deleted file mode 100644
index 4998750..0000000
--- a/include/corkscrew/symbol_table.h
+++ /dev/null
@@ -1,59 +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.
- */
-
-#ifndef _CORKSCREW_SYMBOL_TABLE_H
-#define _CORKSCREW_SYMBOL_TABLE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct {
-    uintptr_t start;
-    uintptr_t end;
-    char* name;
-} symbol_t;
-
-typedef struct {
-    symbol_t* symbols;
-    size_t num_symbols;
-} symbol_table_t;
-
-/*
- * Loads a symbol table from a given file.
- * Returns NULL on error.
- */
-symbol_table_t* load_symbol_table(const char* filename);
-
-/*
- * Frees a symbol table.
- */
-void free_symbol_table(symbol_table_t* table);
-
-/*
- * Finds a symbol associated with an address in the symbol table.
- * Returns NULL if not found.
- */
-const symbol_t* find_symbol(const symbol_table_t* table, uintptr_t addr);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _CORKSCREW_SYMBOL_TABLE_H
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/debugger.h b/include/cutils/debugger.h
index af80e2c..ae6bfc4 100644
--- a/include/cutils/debugger.h
+++ b/include/cutils/debugger.h
@@ -42,6 +42,7 @@
     debugger_action_t action;
     pid_t tid;
     uintptr_t abort_msg_address;
+    int32_t original_si_code;
 } debugger_msg_t;
 
 /* Dumps a process backtrace, registers, and stack to a tombstone file (requires root).
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/sockets.h b/include/cutils/sockets.h
index 19cae0c..daf43ec 100644
--- a/include/cutils/sockets.h
+++ b/include/cutils/sockets.h
@@ -86,6 +86,8 @@
 
 extern int socket_loopback_client(int port, int type);
 extern int socket_network_client(const char *host, int port, int type);
+extern int socket_network_client_timeout(const char *host, int port, int type,
+                                         int timeout);
 extern int socket_loopback_server(int port, int type);
 extern int socket_local_server(const char *name, int namespaceId, int type);
 extern int socket_local_server_bind(int s, const char *name, int namespaceId);
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 bd9de12..946711a 100644
--- a/include/log/log_read.h
+++ b/include/log/log_read.h
@@ -33,6 +33,9 @@
     uint32_t tv_sec; // good to Feb 5 2106
     uint32_t tv_nsec;
 
+    static const uint32_t tv_sec_max = 0xFFFFFFFFUL;
+    static const uint32_t tv_nsec_max = 999999999UL;
+
     log_time(const timespec &T)
     {
         tv_sec = T.tv_sec;
@@ -64,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
     {
@@ -72,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
     {
@@ -81,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 61a7243..03b3506 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 */
@@ -154,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, },
@@ -200,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 f36befb..8838e71 100644
--- a/include/system/audio.h
+++ b/include/system/audio.h
@@ -434,6 +434,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
 };
 
 static inline bool audio_is_output_device(audio_devices_t device)
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 053bfaf..9248ac9 100644
--- a/include/utils/LruCache.h
+++ b/include/utils/LruCache.h
@@ -56,7 +56,7 @@
 
         bool next() {
             mIndex = mCache.mTable->next(mIndex);
-            return mIndex != -1;
+            return (ssize_t)mIndex != -1;
         }
 
         size_t index() const {
@@ -103,9 +103,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/builtins.c b/init/builtins.c
index e2932d5..d9f7bbe 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -33,7 +33,6 @@
 #include <linux/loop.h>
 #include <cutils/partition_utils.h>
 #include <cutils/android_reboot.h>
-#include <sys/system_properties.h>
 #include <fs_mgr.h>
 
 #include <selinux/selinux.h>
@@ -196,6 +195,8 @@
 {
     if (!(svc->flags & SVC_DISABLED)) {
         service_start(svc, NULL);
+    } else {
+        svc->flags |= SVC_DISABLED_START;
     }
 }
 
@@ -238,6 +239,21 @@
     return write_file("/proc/sys/kernel/domainname", args[1]);
 }
 
+int do_enable(int nargs, char **args)
+{
+    struct service *svc;
+    svc = service_find_by_name(args[1]);
+    if (svc) {
+        svc->flags &= ~(SVC_DISABLED | SVC_RC_DISABLED);
+        if (svc->flags & SVC_DISABLED_START) {
+            service_start(svc, NULL);
+        }
+    } else {
+        return -1;
+    }
+    return 0;
+}
+
 int do_exec(int nargs, char **args)
 {
     return -1;
diff --git a/init/devices.c b/init/devices.c
index 80c6d75..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);
@@ -699,7 +737,7 @@
 
 static void handle_device_event(struct uevent *uevent)
 {
-    if (!strcmp(uevent->action,"add") || !strcmp(uevent->action, "change"))
+    if (!strcmp(uevent->action,"add") || !strcmp(uevent->action, "change") || !strcmp(uevent->action, "online"))
         fixup_sys_perms(uevent->path);
 
     if (!strncmp(uevent->subsystem, "block", 5)) {
diff --git a/init/init.c b/init/init.c
index 0884236..c79929b 100644
--- a/init/init.c
+++ b/init/init.c
@@ -46,8 +46,6 @@
 #include <private/android_filesystem_config.h>
 #include <termios.h>
 
-#include <sys/system_properties.h>
-
 #include "devices.h"
 #include "init.h"
 #include "log.h"
@@ -164,7 +162,7 @@
          * state and immediately takes it out of the restarting
          * state if it was in there
          */
-    svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART));
+    svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
     svc->time_started = 0;
 
         /* running processes require no additional work -- if
@@ -364,7 +362,7 @@
 {
     /* The service is still SVC_RUNNING until its process exits, but if it has
      * already exited it shoudn't attempt a restart yet. */
-    svc->flags &= (~SVC_RESTARTING);
+    svc->flags &= ~(SVC_RESTARTING | SVC_DISABLED_START);
 
     if ((how != SVC_DISABLED) && (how != SVC_RESET) && (how != SVC_RESTART)) {
         /* Hrm, an illegal flag.  Default to SVC_DISABLED */
@@ -843,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;
 }
 
@@ -873,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) {
@@ -886,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) {
@@ -908,6 +906,7 @@
         ERROR("SELinux: Unknown value of ro.boot.selinux. Got: \"%s\". Assuming enforcing.\n", tmp);
     }
 
+#endif
     return true;
 }
 
diff --git a/init/init.h b/init/init.h
index 736b75b..c241912 100644
--- a/init/init.h
+++ b/init/init.h
@@ -74,6 +74,7 @@
                                  so it can be restarted with its class */
 #define SVC_RC_DISABLED 0x80  /* Remember if the disabled flag was set in the rc script */
 #define SVC_RESTART     0x100 /* Use to safely restart (stop, wait, start) a service */
+#define SVC_DISABLED_START 0x200 /* a start was requested but it was disabled at the time */
 
 #define NR_SVC_SUPP_GIDS 12    /* twelve supplementary groups */
 
diff --git a/init/init_parser.c b/init/init_parser.c
index f49e698..7800082 100644
--- a/init/init_parser.c
+++ b/init/init_parser.c
@@ -98,6 +98,7 @@
         if (!strcmp(s, "omainname")) return K_domainname;
         break;
     case 'e':
+        if (!strcmp(s, "nable")) return K_enable;
         if (!strcmp(s, "xec")) return K_exec;
         if (!strcmp(s, "xport")) return K_export;
         break;
@@ -759,7 +760,7 @@
         break;
     case K_setenv: { /* name value */
         struct svcenvinfo *ei;
-        if (nargs < 2) {
+        if (nargs < 3) {
             parse_error(state, "setenv option requires name and value arguments\n");
             break;
         }
diff --git a/init/keywords.h b/init/keywords.h
index 97fe50c..6625330 100644
--- a/init/keywords.h
+++ b/init/keywords.h
@@ -6,6 +6,7 @@
 int do_class_stop(int nargs, char **args);
 int do_class_reset(int nargs, char **args);
 int do_domainname(int nargs, char **args);
+int do_enable(int nargs, char **args);
 int do_exec(int nargs, char **args);
 int do_export(int nargs, char **args);
 int do_hostname(int nargs, char **args);
@@ -55,6 +56,7 @@
     KEYWORD(critical,    OPTION,  0, 0)
     KEYWORD(disabled,    OPTION,  0, 0)
     KEYWORD(domainname,  COMMAND, 1, do_domainname)
+    KEYWORD(enable,      COMMAND, 1, do_enable)
     KEYWORD(exec,        COMMAND, 1, do_exec)
     KEYWORD(export,      COMMAND, 2, do_export)
     KEYWORD(group,       OPTION,  0, 0)
diff --git a/init/property_service.c b/init/property_service.c
index eb19f93..fb3bc8d 100644
--- a/init/property_service.c
+++ b/init/property_service.c
@@ -38,7 +38,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>
@@ -90,6 +89,7 @@
     { "log.",             AID_SHELL,    0 },
     { "service.adb.root", AID_SHELL,    0 },
     { "service.adb.tcp.port", AID_SHELL,    0 },
+    { "persist.logd.size",AID_SYSTEM,   0 },
     { "persist.sys.",     AID_SYSTEM,   0 },
     { "persist.service.", AID_SYSTEM,   0 },
     { "persist.security.", AID_SYSTEM,   0 },
@@ -557,7 +557,8 @@
                     || (sb.st_gid != 0)
                     || (sb.st_nlink != 1)) {
                 ERROR("skipping insecure property file %s (uid=%u gid=%u nlink=%d mode=%o)\n",
-                      entry->d_name, sb.st_uid, sb.st_gid, sb.st_nlink, sb.st_mode);
+                      entry->d_name, (unsigned int)sb.st_uid, (unsigned int)sb.st_gid,
+                      sb.st_nlink, sb.st_mode);
                 close(fd);
                 continue;
             }
diff --git a/init/readme.txt b/init/readme.txt
index 42a09cb..613a9e9 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -178,6 +178,16 @@
 domainname <name>
    Set the domain name.
 
+enable <servicename>
+   Turns a disabled service into an enabled one as if the service did not
+   specify disabled.
+   If the service is supposed to be running, it will be started now.
+   Typically used when the bootloader sets a variable that indicates a specific
+   service should be started when needed. E.g.
+     on property:ro.boot.myfancyhardware=1
+        enable my_fancy_service_for_my_fancy_hardware
+
+
 insmod <path>
    Install the module at <path>
 
diff --git a/libbacktrace/Android.build.mk b/libbacktrace/Android.build.mk
index 3c80cc2..9882e31 100644
--- a/libbacktrace/Android.build.mk
+++ b/libbacktrace/Android.build.mk
@@ -60,7 +60,11 @@
     $($(module)_ldlibs_$(build_type)) \
 
 ifeq ($(build_type),target)
-  include external/stlport/libstlport.mk
+  ifneq ($($(module)_libc++),)
+    include external/libcxx/libcxx.mk
+  else
+    include external/stlport/libstlport.mk
+  endif
 
   include $(BUILD_$(build_target))
 endif
@@ -68,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/Android.mk b/libbacktrace/Android.mk
index fdcb162..5a0bc7f 100755
--- a/libbacktrace/Android.mk
+++ b/libbacktrace/Android.mk
@@ -46,10 +46,6 @@
 	libcutils \
 	libgccdemangle \
 
-# To enable using libunwind on each arch, add it to this list.
-libunwind_architectures := arm arm64 mips x86 x86_64
-
-ifeq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),$(libunwind_architectures)))
 libbacktrace_src_files += \
 	UnwindCurrent.cpp \
 	UnwindMap.cpp \
@@ -68,24 +64,6 @@
 libbacktrace_static_libraries_host := \
 	libcutils \
 
-else
-libbacktrace_src_files += \
-	Corkscrew.cpp \
-
-libbacktrace_c_includes := \
-	system/core/libcorkscrew \
-
-libbacktrace_shared_libraries := \
-	libcorkscrew \
-
-libbacktrace_shared_libraries_target += \
-	libdl \
-
-libbacktrace_ldlibs_host := \
-	-ldl \
-
-endif
-
 module := libbacktrace
 module_tag := optional
 build_type := target
@@ -94,6 +72,50 @@
 build_type := host
 include $(LOCAL_PATH)/Android.build.mk
 
+# Don't build for unbundled branches
+ifeq (,$(TARGET_BUILD_APPS))
+#-------------------------------------------------------------------------
+# The libbacktrace library (libc++)
+#-------------------------------------------------------------------------
+libbacktrace_libc++_src_files := \
+	BacktraceImpl.cpp \
+	BacktraceMap.cpp \
+	BacktraceThread.cpp \
+	thread_utils.c \
+
+libbacktrace_libc++_shared_libraries_target := \
+	libcutils \
+	libgccdemangle \
+
+libbacktrace_libc++_src_files += \
+	UnwindCurrent.cpp \
+	UnwindMap.cpp \
+	UnwindPtrace.cpp \
+
+libbacktrace_libc++_c_includes := \
+	external/libunwind/include \
+
+libbacktrace_libc++_shared_libraries := \
+	libunwind \
+	libunwind-ptrace \
+
+libbacktrace_libc++_shared_libraries_host := \
+	liblog \
+
+libbacktrace_libc++_static_libraries_host := \
+	libcutils \
+
+libbacktrace_libc++_libc++ := true
+
+module := libbacktrace_libc++
+module_tag := optional
+build_type := target
+build_target := SHARED_LIBRARY
+include $(LOCAL_PATH)/Android.build.mk
+build_type := host
+include $(LOCAL_PATH)/Android.build.mk
+endif
+
 #-------------------------------------------------------------------------
 # The libbacktrace_test library needed by backtrace_test.
 #-------------------------------------------------------------------------
@@ -118,11 +140,8 @@
 	-fno-builtin \
 	-O0 \
 	-g \
-	-DGTEST_HAS_STD_STRING \
-	-fstack-protector-all \
 
 backtrace_test_cflags_target := \
-	-DGTEST_OS_LINUX_ANDROID \
 	-DENABLE_PSS_TESTS \
 
 backtrace_test_src_files := \
@@ -130,10 +149,8 @@
 	GetPss.cpp \
 	thread_utils.c \
 
-backtrace_test_ldlibs := \
-	-lpthread \
-
 backtrace_test_ldlibs_host := \
+	-lpthread \
 	-lrt \
 
 backtrace_test_shared_libraries := \
@@ -143,6 +160,9 @@
 backtrace_test_shared_libraries_target := \
 	libcutils \
 
+backtrace_test_static_libraries_host := \
+	libcutils \
+
 module := backtrace_test
 module_tag := debug
 build_type := target
diff --git a/libbacktrace/BacktraceImpl.cpp b/libbacktrace/BacktraceImpl.cpp
index 05007d9..405b042 100644
--- a/libbacktrace/BacktraceImpl.cpp
+++ b/libbacktrace/BacktraceImpl.cpp
@@ -19,6 +19,7 @@
 #include <string.h>
 #include <sys/ptrace.h>
 #include <sys/types.h>
+#include <ucontext.h>
 #include <unistd.h>
 
 #include <string>
@@ -55,8 +56,8 @@
   }
 }
 
-bool Backtrace::Unwind(size_t num_ignore_frames) {
-  return impl_->Unwind(num_ignore_frames);
+bool Backtrace::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) {
+  return impl_->Unwind(num_ignore_frames, ucontext);
 }
 
 extern "C" char* __cxa_demangle(const char* mangled, char* buf, size_t* len,
diff --git a/libbacktrace/BacktraceImpl.h b/libbacktrace/BacktraceImpl.h
index 7b31c38..d34ad05 100755
--- a/libbacktrace/BacktraceImpl.h
+++ b/libbacktrace/BacktraceImpl.h
@@ -26,7 +26,7 @@
 public:
   virtual ~BacktraceImpl() { }
 
-  virtual bool Unwind(size_t num_ignore_frames) = 0;
+  virtual bool Unwind(size_t num_ignore_frames, ucontext_t* ucontext) = 0;
 
   // The name returned is not demangled, Backtrace::GetFunctionName()
   // takes care of demangling the name.
diff --git a/libbacktrace/BacktraceMap.cpp b/libbacktrace/BacktraceMap.cpp
index 6eb290d..0056f4b 100644
--- a/libbacktrace/BacktraceMap.cpp
+++ b/libbacktrace/BacktraceMap.cpp
@@ -108,11 +108,11 @@
 
 #if defined(__APPLE__)
   // cmd is guaranteed to always be big enough to hold this string.
-  sprintf(cmd, "vmmap -w -resident -submap -allSplitLibs -interleaved %d", pid_);
+  snprintf(cmd, sizeof(cmd), "vmmap -w -resident -submap -allSplitLibs -interleaved %d", pid_);
   FILE* fp = popen(cmd, "r");
 #else
   // path is guaranteed to always be big enough to hold this string.
-  sprintf(path, "/proc/%d/maps", pid_);
+  snprintf(path, sizeof(path), "/proc/%d/maps", pid_);
   FILE* fp = fopen(path, "r");
 #endif
   if (fp == NULL) {
diff --git a/libbacktrace/BacktraceThread.cpp b/libbacktrace/BacktraceThread.cpp
index 4cda19e..b47cd2a 100644
--- a/libbacktrace/BacktraceThread.cpp
+++ b/libbacktrace/BacktraceThread.cpp
@@ -16,10 +16,15 @@
 
 #include <errno.h>
 #include <inttypes.h>
+#include <limits.h>
+#include <linux/futex.h>
 #include <pthread.h>
 #include <signal.h>
 #include <string.h>
+#include <sys/syscall.h>
+#include <sys/time.h>
 #include <sys/types.h>
+#include <ucontext.h>
 
 #include <cutils/atomic.h>
 
@@ -27,190 +32,179 @@
 #include "BacktraceThread.h"
 #include "thread_utils.h"
 
+static inline int futex(volatile int* uaddr, int op, int val, const struct timespec* ts, volatile int* uaddr2, int val3) {
+  return syscall(__NR_futex, uaddr, op, val, ts, uaddr2, val3);
+}
+
 //-------------------------------------------------------------------------
 // ThreadEntry implementation.
 //-------------------------------------------------------------------------
-static ThreadEntry* g_list = NULL;
-static pthread_mutex_t g_entry_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t g_sigaction_mutex = PTHREAD_MUTEX_INITIALIZER;
+ThreadEntry* ThreadEntry::list_ = NULL;
+pthread_mutex_t ThreadEntry::list_mutex_ = PTHREAD_MUTEX_INITIALIZER;
 
-ThreadEntry::ThreadEntry(
-    BacktraceThreadInterface* intf, pid_t pid, pid_t tid, size_t num_ignore_frames)
-    : thread_intf(intf), pid(pid), tid(tid), next(NULL), prev(NULL),
-      state(STATE_WAITING), num_ignore_frames(num_ignore_frames) {
+// Assumes that ThreadEntry::list_mutex_ has already been locked before
+// creating a ThreadEntry object.
+ThreadEntry::ThreadEntry(pid_t pid, pid_t tid)
+    : pid_(pid), tid_(tid), futex_(0), ref_count_(1), mutex_(PTHREAD_MUTEX_INITIALIZER), next_(ThreadEntry::list_), prev_(NULL) {
+  // Add ourselves to the list.
+  if (ThreadEntry::list_) {
+    ThreadEntry::list_->prev_ = this;
+  }
+  ThreadEntry::list_ = this;
 }
 
-ThreadEntry::~ThreadEntry() {
-  pthread_mutex_lock(&g_entry_mutex);
-  if (g_list == this) {
-    g_list = next;
+ThreadEntry* ThreadEntry::Get(pid_t pid, pid_t tid, bool create) {
+  pthread_mutex_lock(&ThreadEntry::list_mutex_);
+  ThreadEntry* entry = list_;
+  while (entry != NULL) {
+    if (entry->Match(pid, tid)) {
+      break;
+    }
+    entry = entry->next_;
+  }
+
+  if (!entry) {
+    if (create) {
+      entry = new ThreadEntry(pid, tid);
+    }
   } else {
-    if (next) {
-      next->prev = prev;
-    }
-    prev->next = next;
+    entry->ref_count_++;
   }
-  pthread_mutex_unlock(&g_entry_mutex);
-
-  next = NULL;
-  prev = NULL;
-}
-
-ThreadEntry* ThreadEntry::AddThreadToUnwind(
-    BacktraceThreadInterface* intf, pid_t pid, pid_t tid, size_t num_ignore_frames) {
-  ThreadEntry* entry = new ThreadEntry(intf, pid, tid, num_ignore_frames);
-
-  pthread_mutex_lock(&g_entry_mutex);
-  ThreadEntry* cur_entry = g_list;
-  while (cur_entry != NULL) {
-    if (cur_entry->Match(pid, tid)) {
-      // There is already an entry for this pid/tid, this is bad.
-      BACK_LOGW("Entry for pid %d tid %d already exists.", pid, tid);
-
-      pthread_mutex_unlock(&g_entry_mutex);
-      return NULL;
-    }
-    cur_entry = cur_entry->next;
-  }
-
-  // Add the entry to the list.
-  entry->next = g_list;
-  if (g_list) {
-    g_list->prev = entry;
-  }
-  g_list = entry;
-  pthread_mutex_unlock(&g_entry_mutex);
+  pthread_mutex_unlock(&ThreadEntry::list_mutex_);
 
   return entry;
 }
 
+void ThreadEntry::Remove(ThreadEntry* entry) {
+  pthread_mutex_unlock(&entry->mutex_);
+
+  pthread_mutex_lock(&ThreadEntry::list_mutex_);
+  if (--entry->ref_count_ == 0) {
+    delete entry;
+  }
+  pthread_mutex_unlock(&ThreadEntry::list_mutex_);
+}
+
+// Assumes that ThreadEntry::list_mutex_ has already been locked before
+// deleting a ThreadEntry object.
+ThreadEntry::~ThreadEntry() {
+  if (list_ == this) {
+    list_ = next_;
+  } else {
+    if (next_) {
+      next_->prev_ = prev_;
+    }
+    prev_->next_ = next_;
+  }
+
+  next_ = NULL;
+  prev_ = NULL;
+}
+
+void ThreadEntry::Wait(int value) {
+  timespec ts;
+  ts.tv_sec = 10;
+  ts.tv_nsec = 0;
+  errno = 0;
+  futex(&futex_, FUTEX_WAIT, value, &ts, NULL, 0);
+  if (errno != 0 && errno != EWOULDBLOCK) {
+    BACK_LOGW("futex wait failed, futex = %d: %s", futex_, strerror(errno));
+  }
+}
+
+void ThreadEntry::Wake() {
+  futex_++;
+  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.
 //-------------------------------------------------------------------------
-static void SignalHandler(int n __attribute__((unused)), siginfo_t* siginfo,
-                          void* sigcontext) {
-  if (pthread_mutex_lock(&g_entry_mutex) == 0) {
-    pid_t pid = getpid();
-    pid_t tid = gettid();
-    ThreadEntry* cur_entry = g_list;
-    while (cur_entry) {
-      if (cur_entry->Match(pid, tid)) {
-        break;
-      }
-      cur_entry = cur_entry->next;
-    }
-    pthread_mutex_unlock(&g_entry_mutex);
-    if (!cur_entry) {
-      BACK_LOGW("Unable to find pid %d tid %d information", pid, tid);
-      return;
-    }
+static pthread_mutex_t g_sigaction_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-    if (android_atomic_acquire_cas(STATE_WAITING, STATE_DUMPING, &cur_entry->state) == 0) {
-      cur_entry->thread_intf->ThreadUnwind(siginfo, sigcontext,
-                                           cur_entry->num_ignore_frames);
-    }
-    android_atomic_release_store(STATE_DONE, &cur_entry->state);
+static void SignalHandler(int, siginfo_t*, void* sigcontext) {
+  ThreadEntry* entry = ThreadEntry::Get(getpid(), gettid(), false);
+  if (!entry) {
+    BACK_LOGW("Unable to find pid %d tid %d information", getpid(), gettid());
+    return;
   }
+
+  entry->CopyUcontextFromSigcontext(sigcontext);
+
+  // Indicate the ucontext is now valid.
+  entry->Wake();
+
+  // Pause the thread until the unwind is complete. This avoids having
+  // the thread run ahead causing problems.
+  entry->Wait(1);
+
+  ThreadEntry::Remove(entry);
 }
 
-BacktraceThread::BacktraceThread(
-    BacktraceImpl* impl, BacktraceThreadInterface* thread_intf, pid_t tid,
-    BacktraceMap* map)
-    : BacktraceCurrent(impl, map), thread_intf_(thread_intf) {
+BacktraceThread::BacktraceThread(BacktraceImpl* impl, pid_t tid, BacktraceMap* map)
+    : BacktraceCurrent(impl, map) {
   tid_ = tid;
 }
 
 BacktraceThread::~BacktraceThread() {
 }
 
-void BacktraceThread::FinishUnwind() {
-  for (std::vector<backtrace_frame_data_t>::iterator it = frames_.begin();
-       it != frames_.end(); ++it) {
-    it->map = FindMap(it->pc);
-
-    it->func_offset = 0;
-    it->func_name = GetFunctionName(it->pc, &it->func_offset);
-  }
-}
-
-bool BacktraceThread::TriggerUnwindOnThread(ThreadEntry* entry) {
-  entry->state = STATE_WAITING;
-
-  if (tgkill(Pid(), Tid(), SIGURG) != 0) {
-    BACK_LOGW("tgkill failed %s", strerror(errno));
-    return false;
-  }
-
-  // Allow up to ten seconds for the dump to start.
-  int wait_millis = 10000;
-  int32_t state;
-  while (true) {
-    state = android_atomic_acquire_load(&entry->state);
-    if (state != STATE_WAITING) {
-      break;
-    }
-    if (wait_millis--) {
-      usleep(1000);
-    } else {
-      break;
-    }
-  }
-
-  bool cancelled = false;
-  if (state == STATE_WAITING) {
-    if (android_atomic_acquire_cas(state, STATE_CANCEL, &entry->state) == 0) {
-      BACK_LOGW("Cancelled dump of thread %d", entry->tid);
-      state = STATE_CANCEL;
-      cancelled = true;
-    } else {
-      state = android_atomic_acquire_load(&entry->state);
-    }
-  }
-
-  // Wait for at most ten seconds for the cancel or dump to finish.
-  wait_millis = 10000;
-  while (android_atomic_acquire_load(&entry->state) != STATE_DONE) {
-    if (wait_millis--) {
-      usleep(1000);
-    } else {
-      BACK_LOGW("Didn't finish thread unwind in 60 seconds.");
-      break;
-    }
-  }
-  return !cancelled;
-}
-
-bool BacktraceThread::Unwind(size_t num_ignore_frames) {
-  ThreadEntry* entry = ThreadEntry::AddThreadToUnwind(
-      thread_intf_, Pid(), Tid(), num_ignore_frames);
-  if (!entry) {
-    return false;
+bool BacktraceThread::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) {
+  if (ucontext) {
+    // Unwind using an already existing ucontext.
+    return impl_->Unwind(num_ignore_frames, ucontext);
   }
 
   // Prevent multiple threads trying to set the trigger action on different
   // threads at the same time.
-  bool retval = false;
-  if (pthread_mutex_lock(&g_sigaction_mutex) == 0) {
-    struct sigaction act, oldact;
-    memset(&act, 0, sizeof(act));
-    act.sa_sigaction = SignalHandler;
-    act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
-    sigemptyset(&act.sa_mask);
-    if (sigaction(SIGURG, &act, &oldact) == 0) {
-      retval = TriggerUnwindOnThread(entry);
-      sigaction(SIGURG, &oldact, NULL);
-    } else {
-      BACK_LOGW("sigaction failed %s", strerror(errno));
-    }
+  if (pthread_mutex_lock(&g_sigaction_mutex) < 0) {
+    BACK_LOGW("sigaction failed: %s", strerror(errno));
+    return false;
+  }
+
+  ThreadEntry* entry = ThreadEntry::Get(Pid(), Tid());
+  entry->Lock();
+
+  struct sigaction act, oldact;
+  memset(&act, 0, sizeof(act));
+  act.sa_sigaction = SignalHandler;
+  act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
+  sigemptyset(&act.sa_mask);
+  if (sigaction(THREAD_SIGNAL, &act, &oldact) != 0) {
+    BACK_LOGW("sigaction failed %s", strerror(errno));
+    entry->Unlock();
+    ThreadEntry::Remove(entry);
     pthread_mutex_unlock(&g_sigaction_mutex);
-  } else {
-    BACK_LOGW("unable to acquire sigaction mutex.");
+    return false;
   }
 
-  if (retval) {
-    FinishUnwind();
+  if (tgkill(Pid(), Tid(), THREAD_SIGNAL) != 0) {
+    BACK_LOGW("tgkill %d failed: %s", Tid(), strerror(errno));
+    sigaction(THREAD_SIGNAL, &oldact, NULL);
+    entry->Unlock();
+    ThreadEntry::Remove(entry);
+    pthread_mutex_unlock(&g_sigaction_mutex);
+    return false;
   }
-  delete entry;
 
-  return retval;
+  // Wait for the thread to get the ucontext.
+  entry->Wait(0);
+
+  // After the thread has received the signal, allow other unwinders to
+  // continue.
+  sigaction(THREAD_SIGNAL, &oldact, NULL);
+  pthread_mutex_unlock(&g_sigaction_mutex);
+
+  bool unwind_done = impl_->Unwind(num_ignore_frames, entry->GetUcontext());
+
+  // Tell the signal handler to exit and release the entry.
+  entry->Wake();
+
+  return unwind_done;
 }
diff --git a/libbacktrace/BacktraceThread.h b/libbacktrace/BacktraceThread.h
index 3412d58..ff3e9f3 100644
--- a/libbacktrace/BacktraceThread.h
+++ b/libbacktrace/BacktraceThread.h
@@ -18,73 +18,71 @@
 #define _LIBBACKTRACE_BACKTRACE_THREAD_H
 
 #include <inttypes.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
 #include <sys/types.h>
+#include <ucontext.h>
 
 #include "BacktraceImpl.h"
 
-enum state_e {
-  STATE_WAITING = 0,
-  STATE_DUMPING,
-  STATE_DONE,
-  STATE_CANCEL,
-};
+// The signal used to cause a thread to dump the stack.
+#if defined(__GLIBC__)
+// GLIBC reserves __SIGRTMIN signals, so use SIGRTMIN to avoid errors.
+#define THREAD_SIGNAL SIGRTMIN
+#else
+#define THREAD_SIGNAL (__SIGRTMIN+1)
+#endif
 
-class BacktraceThreadInterface;
+class ThreadEntry {
+public:
+  static ThreadEntry* Get(pid_t pid, pid_t tid, bool create = true);
 
-struct ThreadEntry {
-  ThreadEntry(
-      BacktraceThreadInterface* impl, pid_t pid, pid_t tid,
-      size_t num_ignore_frames);
+  static void Remove(ThreadEntry* entry);
+
+  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.
+    futex_ = 0;
+  }
+
+  inline void Unlock() {
+    pthread_mutex_unlock(&mutex_);
+  }
+
+  inline ucontext_t* GetUcontext() { return &ucontext_; }
+
+private:
+  ThreadEntry(pid_t pid, pid_t tid);
   ~ThreadEntry();
 
-  bool Match(pid_t chk_pid, pid_t chk_tid) { return (chk_pid == pid && chk_tid == tid); }
+  bool Match(pid_t chk_pid, pid_t chk_tid) { return (chk_pid == pid_ && chk_tid == tid_); }
 
-  static ThreadEntry* AddThreadToUnwind(
-      BacktraceThreadInterface* thread_intf, pid_t pid, pid_t tid,
-      size_t num_ignored_frames);
+  pid_t pid_;
+  pid_t tid_;
+  int futex_;
+  int ref_count_;
+  pthread_mutex_t mutex_;
+  ThreadEntry* next_;
+  ThreadEntry* prev_;
+  ucontext_t ucontext_;
 
-  BacktraceThreadInterface* thread_intf;
-  pid_t pid;
-  pid_t tid;
-  ThreadEntry* next;
-  ThreadEntry* prev;
-  int32_t state;
-  int num_ignore_frames;
-};
-
-// Interface class that does not contain any local storage, only defines
-// virtual functions to be defined by subclasses.
-class BacktraceThreadInterface {
-public:
-  virtual ~BacktraceThreadInterface() { }
-
-  virtual void ThreadUnwind(
-      siginfo_t* siginfo, void* sigcontext, size_t num_ignore_frames) = 0;
+  static ThreadEntry* list_;
+  static pthread_mutex_t list_mutex_;
 };
 
 class BacktraceThread : public BacktraceCurrent {
 public:
-  // impl and thread_intf should point to the same object, this allows
-  // the compiler to catch if an implementation does not properly
-  // subclass both.
-  BacktraceThread(
-      BacktraceImpl* impl, BacktraceThreadInterface* thread_intf, pid_t tid,
-      BacktraceMap* map);
+  BacktraceThread(BacktraceImpl* impl, pid_t tid, BacktraceMap* map);
   virtual ~BacktraceThread();
 
-  virtual bool Unwind(size_t num_ignore_frames);
-
-  virtual void ThreadUnwind(
-      siginfo_t* siginfo, void* sigcontext, size_t num_ignore_frames) {
-    thread_intf_->ThreadUnwind(siginfo, sigcontext, num_ignore_frames);
-  }
-
-private:
-  virtual bool TriggerUnwindOnThread(ThreadEntry* entry);
-
-  virtual void FinishUnwind();
-
-  BacktraceThreadInterface* thread_intf_;
+  virtual bool Unwind(size_t num_ignore_frames, ucontext_t* ucontext);
 };
 
 #endif // _LIBBACKTRACE_BACKTRACE_THREAD_H
diff --git a/libbacktrace/Corkscrew.cpp b/libbacktrace/Corkscrew.cpp
deleted file mode 100644
index 773b0a2..0000000
--- a/libbacktrace/Corkscrew.cpp
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2013 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 <backtrace/Backtrace.h>
-
-#include <string.h>
-
-#include <backtrace-arch.h>
-#include <corkscrew/backtrace.h>
-
-#ifndef __USE_GNU
-#define __USE_GNU
-#endif
-#include <dlfcn.h>
-
-#include "BacktraceLog.h"
-#include "Corkscrew.h"
-
-//-------------------------------------------------------------------------
-// CorkscrewMap functions.
-//-------------------------------------------------------------------------
-CorkscrewMap::CorkscrewMap(pid_t pid) : BacktraceMap(pid), map_info_(NULL) {
-}
-
-CorkscrewMap::~CorkscrewMap() {
-  if (map_info_) {
-    free_map_info_list(map_info_);
-    map_info_ = NULL;
-  }
-}
-
-bool CorkscrewMap::Build() {
-  map_info_ = load_map_info_list(pid_);
-
-  // Use the information in map_info_ to construct the BacktraceMap data
-  // rather than reparsing /proc/self/maps.
-  map_info_t* cur_map = map_info_;
-  while (cur_map) {
-    backtrace_map_t map;
-    map.start = cur_map->start;
-    map.end = cur_map->end;
-    map.flags = 0;
-    if (cur_map->is_readable) {
-      map.flags |= PROT_READ;
-    }
-    if (cur_map->is_writable) {
-      map.flags |= PROT_WRITE;
-    }
-    if (cur_map->is_executable) {
-      map.flags |= PROT_EXEC;
-    }
-    map.name = cur_map->name;
-
-    // The maps are in descending order, but we want them in ascending order.
-    maps_.push_front(map);
-
-    cur_map = cur_map->next;
-  }
-  return map_info_ != NULL;
-}
-
-//-------------------------------------------------------------------------
-// CorkscrewCommon functions.
-//-------------------------------------------------------------------------
-bool CorkscrewCommon::GenerateFrameData(
-    backtrace_frame_t* cork_frames, ssize_t num_frames) {
-  if (num_frames < 0) {
-    BACK_LOGW("libcorkscrew unwind failed.");
-    return false;
-  }
-
-  std::vector<backtrace_frame_data_t>* frames = GetFrames();
-  frames->resize(num_frames);
-  size_t i = 0;
-  for (std::vector<backtrace_frame_data_t>::iterator it = frames->begin();
-       it != frames->end(); ++it, ++i) {
-    it->num = i;
-    it->pc = cork_frames[i].absolute_pc;
-    it->sp = cork_frames[i].stack_top;
-    it->stack_size = cork_frames[i].stack_size;
-    it->func_offset = 0;
-
-    it->map = FindMap(it->pc);
-    it->func_name = GetFunctionName(it->pc, &it->func_offset);
-  }
-  return true;
-}
-
-//-------------------------------------------------------------------------
-// CorkscrewCurrent functions.
-//-------------------------------------------------------------------------
-CorkscrewCurrent::CorkscrewCurrent() {
-}
-
-CorkscrewCurrent::~CorkscrewCurrent() {
-}
-
-bool CorkscrewCurrent::Unwind(size_t num_ignore_frames) {
-  backtrace_frame_t frames[MAX_BACKTRACE_FRAMES];
-  ssize_t num_frames = unwind_backtrace(frames, num_ignore_frames, MAX_BACKTRACE_FRAMES);
-
-  return GenerateFrameData(frames, num_frames);
-}
-
-std::string CorkscrewCurrent::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) {
-  *offset = 0;
-
-  Dl_info info;
-  const backtrace_map_t* map = FindMap(pc);
-  if (map) {
-    if (dladdr((const void*)pc, &info)) {
-      if (info.dli_sname) {
-        *offset = pc - map->start - (uintptr_t)info.dli_saddr + (uintptr_t)info.dli_fbase;
-        return info.dli_sname;
-      }
-    } else {
-      // dladdr(3) didn't find a symbol; maybe it's static? Look in the ELF file...
-      symbol_table_t* symbol_table = load_symbol_table(map->name.c_str());
-      if (symbol_table) {
-        // First check if we can find the symbol using a relative pc.
-        std::string name;
-        const symbol_t* elf_symbol = find_symbol(symbol_table, pc - map->start);
-        if (elf_symbol) {
-          name = elf_symbol->name;
-          *offset = pc - map->start - elf_symbol->start;
-        } else if ((elf_symbol = find_symbol(symbol_table, pc)) != NULL) {
-          // Found the symbol using the absolute pc.
-          name = elf_symbol->name;
-          *offset = pc - elf_symbol->start;
-        }
-        free_symbol_table(symbol_table);
-        return name;
-      }
-    }
-  }
-  return "";
-}
-
-//-------------------------------------------------------------------------
-// CorkscrewThread functions.
-//-------------------------------------------------------------------------
-CorkscrewThread::CorkscrewThread() {
-}
-
-CorkscrewThread::~CorkscrewThread() {
-}
-
-void CorkscrewThread::ThreadUnwind(
-    siginfo_t* siginfo, void* sigcontext, size_t num_ignore_frames) {
-  backtrace_frame_t cork_frames[MAX_BACKTRACE_FRAMES];
-  CorkscrewMap* map = static_cast<CorkscrewMap*>(GetMap());
-  ssize_t num_frames = unwind_backtrace_signal_arch(
-      siginfo, sigcontext, map->GetMapInfo(), cork_frames,
-      num_ignore_frames, MAX_BACKTRACE_FRAMES);
-  if (num_frames > 0) {
-    std::vector<backtrace_frame_data_t>* frames = GetFrames();
-    frames->resize(num_frames);
-    size_t i = 0;
-    for (std::vector<backtrace_frame_data_t>::iterator it = frames->begin();
-         it != frames->end(); ++it, ++i) {
-      it->num = i;
-      it->pc = cork_frames[i].absolute_pc;
-      it->sp = cork_frames[i].stack_top;
-      it->stack_size = cork_frames[i].stack_size;
-      it->map = NULL;
-      it->func_offset = 0;
-    }
-  }
-}
-
-//-------------------------------------------------------------------------
-// CorkscrewPtrace functions.
-//-------------------------------------------------------------------------
-CorkscrewPtrace::CorkscrewPtrace() : ptrace_context_(NULL) {
-}
-
-CorkscrewPtrace::~CorkscrewPtrace() {
-  if (ptrace_context_) {
-    free_ptrace_context(ptrace_context_);
-    ptrace_context_ = NULL;
-  }
-}
-
-bool CorkscrewPtrace::Unwind(size_t num_ignore_frames) {
-  ptrace_context_ = load_ptrace_context(Tid());
-
-  backtrace_frame_t frames[MAX_BACKTRACE_FRAMES];
-  ssize_t num_frames = unwind_backtrace_ptrace(
-      Tid(), ptrace_context_, frames, num_ignore_frames, MAX_BACKTRACE_FRAMES);
-
-  return GenerateFrameData(frames, num_frames);
-}
-
-std::string CorkscrewPtrace::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) {
-  // Get information about a different process.
-  const map_info_t* map_info;
-  const symbol_t* symbol;
-  find_symbol_ptrace(ptrace_context_, pc, &map_info, &symbol);
-  char* symbol_name = NULL;
-  if (symbol) {
-    if (map_info) {
-      *offset = pc - map_info->start - symbol->start;
-    }
-    symbol_name = symbol->name;
-    return symbol_name;
-  }
-
-  return "";
-}
-
-//-------------------------------------------------------------------------
-// C++ object creation functions.
-//-------------------------------------------------------------------------
-Backtrace* CreateCurrentObj(BacktraceMap* map) {
-  return new BacktraceCurrent(new CorkscrewCurrent(), map);
-}
-
-Backtrace* CreatePtraceObj(pid_t pid, pid_t tid, BacktraceMap* map) {
-  return new BacktracePtrace(new CorkscrewPtrace(), pid, tid, map);
-}
-
-Backtrace* CreateThreadObj(pid_t tid, BacktraceMap* map) {
-  CorkscrewThread* thread_obj = new CorkscrewThread();
-  return new BacktraceThread(thread_obj, thread_obj, tid, map);
-}
-
-//-------------------------------------------------------------------------
-// BacktraceMap create function.
-//-------------------------------------------------------------------------
-BacktraceMap* BacktraceMap::Create(pid_t pid) {
-  BacktraceMap* map = new CorkscrewMap(pid);
-  if (!map->Build()) {
-    delete map;
-    return NULL;
-  }
-  return map;
-}
diff --git a/libbacktrace/Corkscrew.h b/libbacktrace/Corkscrew.h
deleted file mode 100644
index 1633398..0000000
--- a/libbacktrace/Corkscrew.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2013 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 _LIBBACKTRACE_CORKSCREW_H
-#define _LIBBACKTRACE_CORKSCREW_H
-
-#include <inttypes.h>
-
-#include <string>
-
-#include <backtrace/Backtrace.h>
-#include <backtrace/BacktraceMap.h>
-
-#include <corkscrew/backtrace.h>
-
-#include "BacktraceImpl.h"
-#include "BacktraceThread.h"
-
-class CorkscrewMap : public BacktraceMap {
-public:
-  CorkscrewMap(pid_t pid);
-  virtual ~CorkscrewMap();
-
-  virtual bool Build();
-
-  map_info_t* GetMapInfo() { return map_info_; }
-
-private:
-  map_info_t* map_info_;
-};
-
-class CorkscrewCommon : public BacktraceImpl {
-public:
-  bool GenerateFrameData(backtrace_frame_t* cork_frames, ssize_t num_frames);
-};
-
-class CorkscrewCurrent : public CorkscrewCommon {
-public:
-  CorkscrewCurrent();
-  virtual ~CorkscrewCurrent();
-
-  virtual bool Unwind(size_t num_ignore_threads);
-
-  virtual std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset);
-};
-
-class CorkscrewThread : public CorkscrewCurrent, public BacktraceThreadInterface {
-public:
-  CorkscrewThread();
-  virtual ~CorkscrewThread();
-
-  virtual void ThreadUnwind(
-      siginfo_t* siginfo, void* sigcontext, size_t num_ignore_frames);
-};
-
-class CorkscrewPtrace : public CorkscrewCommon {
-public:
-  CorkscrewPtrace();
-  virtual ~CorkscrewPtrace();
-
-  virtual std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset);
-
-  virtual bool Unwind(size_t num_ignore_threads);
-
-private:
-  ptrace_context_t* ptrace_context_;
-};
-
-#endif // _LIBBACKTRACE_CORKSCREW_H
diff --git a/libbacktrace/UnwindCurrent.cpp b/libbacktrace/UnwindCurrent.cpp
index 67d372a..b176aaf 100755
--- a/libbacktrace/UnwindCurrent.cpp
+++ b/libbacktrace/UnwindCurrent.cpp
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include <sys/ucontext.h>
 #include <sys/types.h>
+#include <ucontext.h>
 
 #include <backtrace/Backtrace.h>
 #include <backtrace/BacktraceMap.h>
@@ -24,6 +24,7 @@
 #include <libunwind.h>
 
 #include "BacktraceLog.h"
+#include "BacktraceThread.h"
 #include "UnwindCurrent.h"
 #include "UnwindMap.h"
 
@@ -36,15 +37,45 @@
 UnwindCurrent::~UnwindCurrent() {
 }
 
-bool UnwindCurrent::Unwind(size_t num_ignore_frames) {
-  int ret = unw_getcontext(&context_);
-  if (ret < 0) {
-    BACK_LOGW("unw_getcontext failed %d", ret);
-    return false;
+bool UnwindCurrent::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) {
+  if (!ucontext) {
+    int ret = unw_getcontext(&context_);
+    if (ret < 0) {
+      BACK_LOGW("unw_getcontext failed %d", ret);
+      return false;
+    }
+  }
+  else {
+    GetUnwContextFromUcontext(ucontext);
   }
   return UnwindFromContext(num_ignore_frames, false);
 }
 
+void UnwindCurrent::GetUnwContextFromUcontext(const ucontext_t* ucontext) {
+  unw_tdep_context_t* unw_context = reinterpret_cast<unw_tdep_context_t*>(&context_);
+
+#if defined(__arm__)
+  unw_context->regs[0] = ucontext->uc_mcontext.arm_r0;
+  unw_context->regs[1] = ucontext->uc_mcontext.arm_r1;
+  unw_context->regs[2] = ucontext->uc_mcontext.arm_r2;
+  unw_context->regs[3] = ucontext->uc_mcontext.arm_r3;
+  unw_context->regs[4] = ucontext->uc_mcontext.arm_r4;
+  unw_context->regs[5] = ucontext->uc_mcontext.arm_r5;
+  unw_context->regs[6] = ucontext->uc_mcontext.arm_r6;
+  unw_context->regs[7] = ucontext->uc_mcontext.arm_r7;
+  unw_context->regs[8] = ucontext->uc_mcontext.arm_r8;
+  unw_context->regs[9] = ucontext->uc_mcontext.arm_r9;
+  unw_context->regs[10] = ucontext->uc_mcontext.arm_r10;
+  unw_context->regs[11] = ucontext->uc_mcontext.arm_fp;
+  unw_context->regs[12] = ucontext->uc_mcontext.arm_ip;
+  unw_context->regs[13] = ucontext->uc_mcontext.arm_sp;
+  unw_context->regs[14] = ucontext->uc_mcontext.arm_lr;
+  unw_context->regs[15] = ucontext->uc_mcontext.arm_pc;
+#else
+  unw_context->uc_mcontext = ucontext->uc_mcontext;
+#endif
+}
+
 std::string UnwindCurrent::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) {
   *offset = 0;
   char buf[512];
@@ -122,47 +153,6 @@
   return true;
 }
 
-void UnwindCurrent::ExtractContext(void* sigcontext) {
-  unw_tdep_context_t* context = reinterpret_cast<unw_tdep_context_t*>(&context_);
-  const ucontext_t* uc = reinterpret_cast<const ucontext_t*>(sigcontext);
-
-#if defined(__arm__)
-  context->regs[0] = uc->uc_mcontext.arm_r0;
-  context->regs[1] = uc->uc_mcontext.arm_r1;
-  context->regs[2] = uc->uc_mcontext.arm_r2;
-  context->regs[3] = uc->uc_mcontext.arm_r3;
-  context->regs[4] = uc->uc_mcontext.arm_r4;
-  context->regs[5] = uc->uc_mcontext.arm_r5;
-  context->regs[6] = uc->uc_mcontext.arm_r6;
-  context->regs[7] = uc->uc_mcontext.arm_r7;
-  context->regs[8] = uc->uc_mcontext.arm_r8;
-  context->regs[9] = uc->uc_mcontext.arm_r9;
-  context->regs[10] = uc->uc_mcontext.arm_r10;
-  context->regs[11] = uc->uc_mcontext.arm_fp;
-  context->regs[12] = uc->uc_mcontext.arm_ip;
-  context->regs[13] = uc->uc_mcontext.arm_sp;
-  context->regs[14] = uc->uc_mcontext.arm_lr;
-  context->regs[15] = uc->uc_mcontext.arm_pc;
-#else
-  context->uc_mcontext = uc->uc_mcontext;
-#endif
-}
-
-//-------------------------------------------------------------------------
-// UnwindThread functions.
-//-------------------------------------------------------------------------
-UnwindThread::UnwindThread() {
-}
-
-UnwindThread::~UnwindThread() {
-}
-
-void UnwindThread::ThreadUnwind(
-    siginfo_t* /*siginfo*/, void* sigcontext, size_t num_ignore_frames) {
-  ExtractContext(sigcontext);
-  UnwindFromContext(num_ignore_frames, true);
-}
-
 //-------------------------------------------------------------------------
 // C++ object creation function.
 //-------------------------------------------------------------------------
@@ -171,6 +161,5 @@
 }
 
 Backtrace* CreateThreadObj(pid_t tid, BacktraceMap* map) {
-  UnwindThread* thread_obj = new UnwindThread();
-  return new BacktraceThread(thread_obj, thread_obj, tid, map);
+  return new BacktraceThread(new UnwindCurrent(), tid, map);
 }
diff --git a/libbacktrace/UnwindCurrent.h b/libbacktrace/UnwindCurrent.h
index 41080c7..2375e6e 100644
--- a/libbacktrace/UnwindCurrent.h
+++ b/libbacktrace/UnwindCurrent.h
@@ -20,7 +20,6 @@
 #include <string>
 
 #include "BacktraceImpl.h"
-#include "BacktraceThread.h"
 
 #define UNW_LOCAL_ONLY
 #include <libunwind.h>
@@ -30,25 +29,16 @@
   UnwindCurrent();
   virtual ~UnwindCurrent();
 
-  virtual bool Unwind(size_t num_ignore_frames);
+  virtual bool Unwind(size_t num_ignore_frames, ucontext_t* ucontext);
 
   virtual std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset);
 
   bool UnwindFromContext(size_t num_ignore_frames, bool within_handler);
 
-  void ExtractContext(void* sigcontext);
+  void GetUnwContextFromUcontext(const ucontext_t* context);
 
 protected:
   unw_context_t context_;
 };
 
-class UnwindThread : public UnwindCurrent, public BacktraceThreadInterface {
-public:
-  UnwindThread();
-  virtual ~UnwindThread();
-
-  virtual void ThreadUnwind(
-      siginfo_t* siginfo, void* sigcontext, size_t num_ignore_frames);
-};
-
 #endif // _LIBBACKTRACE_UNWIND_CURRENT_H
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/libbacktrace/UnwindPtrace.cpp b/libbacktrace/UnwindPtrace.cpp
index 5ca7e60..7ba8775 100644
--- a/libbacktrace/UnwindPtrace.cpp
+++ b/libbacktrace/UnwindPtrace.cpp
@@ -19,6 +19,7 @@
 
 #include <sys/types.h>
 #include <string.h>
+#include <ucontext.h>
 
 #include <libunwind.h>
 #include <libunwind-ptrace.h>
@@ -45,7 +46,12 @@
   }
 }
 
-bool UnwindPtrace::Unwind(size_t num_ignore_frames) {
+bool UnwindPtrace::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) {
+  if (ucontext) {
+    BACK_LOGW("Unwinding from a specified context not supported yet.");
+    return false;
+  }
+
   addr_space_ = unw_create_addr_space(&_UPT_accessors, 0);
   if (!addr_space_) {
     BACK_LOGW("unw_create_addr_space failed.");
diff --git a/libbacktrace/UnwindPtrace.h b/libbacktrace/UnwindPtrace.h
index 1e82117..2fb7967 100644
--- a/libbacktrace/UnwindPtrace.h
+++ b/libbacktrace/UnwindPtrace.h
@@ -28,7 +28,7 @@
   UnwindPtrace();
   virtual ~UnwindPtrace();
 
-  virtual bool Unwind(size_t num_ignore_frames);
+  virtual bool Unwind(size_t num_ignore_frames, ucontext_t* ucontext);
 
   virtual std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset);
 
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index a5e141b..ed6b211 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -33,6 +33,9 @@
 #include <backtrace/BacktraceMap.h>
 #include <UniquePtr.h>
 
+// For the THREAD_SIGNAL definition.
+#include "BacktraceThread.h"
+
 #include <cutils/atomic.h>
 #include <gtest/gtest.h>
 
@@ -460,9 +463,15 @@
   // Wait up to 2 seconds for the tid to be set.
   ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));
 
+  // Make sure that the thread signal used is not visible when compiled for
+  // the target.
+#if !defined(__GLIBC__)
+  ASSERT_LT(THREAD_SIGNAL, SIGRTMIN);
+#endif
+
   // Save the current signal action and make sure it is restored afterwards.
   struct sigaction cur_action;
-  ASSERT_TRUE(sigaction(SIGURG, NULL, &cur_action) == 0);
+  ASSERT_TRUE(sigaction(THREAD_SIGNAL, NULL, &cur_action) == 0);
 
   UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid));
   ASSERT_TRUE(backtrace.get() != NULL);
@@ -475,7 +484,7 @@
 
   // Verify that the old action was restored.
   struct sigaction new_action;
-  ASSERT_TRUE(sigaction(SIGURG, NULL, &new_action) == 0);
+  ASSERT_TRUE(sigaction(THREAD_SIGNAL, NULL, &new_action) == 0);
   EXPECT_EQ(cur_action.sa_sigaction, new_action.sa_sigaction);
   EXPECT_EQ(cur_action.sa_flags, new_action.sa_flags);
 }
@@ -606,6 +615,49 @@
   }
 }
 
+TEST(libbacktrace, thread_multiple_dump_same_thread) {
+  pthread_attr_t attr;
+  pthread_attr_init(&attr);
+  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+  thread_t runner;
+  runner.tid = 0;
+  runner.state = 0;
+  ASSERT_TRUE(pthread_create(&runner.threadId, &attr, ThreadMaxRun, &runner) == 0);
+
+  // Wait for tids to be set.
+  ASSERT_TRUE(WaitForNonZero(&runner.state, 10));
+
+  // Start all of the dumpers at once, they will spin until they are signalled
+  // to begin their dump run.
+  int32_t dump_now = 0;
+  // Dump the same thread NUM_THREADS simultaneously.
+  std::vector<dump_thread_t> dumpers(NUM_THREADS);
+  for (size_t i = 0; i < NUM_THREADS; i++) {
+    dumpers[i].thread.tid = runner.tid;
+    dumpers[i].thread.state = 0;
+    dumpers[i].done = 0;
+    dumpers[i].now = &dump_now;
+
+    ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0);
+  }
+
+  // Start all of the dumpers going at once.
+  android_atomic_acquire_store(1, &dump_now);
+
+  for (size_t i = 0; i < NUM_THREADS; i++) {
+    ASSERT_TRUE(WaitForNonZero(&dumpers[i].done, 100));
+
+    ASSERT_TRUE(dumpers[i].backtrace != NULL);
+    VerifyMaxDump(dumpers[i].backtrace);
+
+    delete dumpers[i].backtrace;
+    dumpers[i].backtrace = NULL;
+  }
+
+  // Tell the runner thread to exit its infinite loop.
+  android_atomic_acquire_store(0, &runner.state);
+}
+
 // This test is for UnwindMaps that should share the same map cursor when
 // multiple maps are created for the current process at the same time.
 TEST(libbacktrace, simultaneous_maps) {
diff --git a/libcorkscrew/Android.mk b/libcorkscrew/Android.mk
deleted file mode 100644
index 8f3b68c..0000000
--- a/libcorkscrew/Android.mk
+++ /dev/null
@@ -1,100 +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.
-
-LOCAL_PATH:= $(call my-dir)
-
-generic_src_files := \
-	backtrace.c \
-	backtrace-helper.c \
-	demangle.c \
-	map_info.c \
-	ptrace.c \
-	symbol_table.c
-
-arm_src_files := \
-	arch-arm/backtrace-arm.c \
-	arch-arm/ptrace-arm.c
-
-x86_src_files := \
-	arch-x86/backtrace-x86.c \
-	arch-x86/ptrace-x86.c
-
-ifneq ($(TARGET_IS_64_BIT),true)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(generic_src_files)
-
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_SRC_FILES += $(arm_src_files)
-LOCAL_CFLAGS += -DCORKSCREW_HAVE_ARCH
-endif
-ifeq ($(TARGET_ARCH),x86)
-LOCAL_SRC_FILES += $(x86_src_files)
-LOCAL_CFLAGS += -DCORKSCREW_HAVE_ARCH
-endif
-ifeq ($(TARGET_ARCH),mips)
-LOCAL_SRC_FILES += \
-	arch-mips/backtrace-mips.c \
-	arch-mips/ptrace-mips.c
-LOCAL_CFLAGS += -DCORKSCREW_HAVE_ARCH
-endif
-
-LOCAL_SHARED_LIBRARIES += libdl libcutils liblog libgccdemangle
-
-LOCAL_CFLAGS += -std=gnu99 -Werror -Wno-unused-parameter
-LOCAL_MODULE := libcorkscrew
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
-# Build test.
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := test.cpp
-LOCAL_CFLAGS += -Werror -fno-inline-small-functions
-LOCAL_SHARED_LIBRARIES := libcorkscrew
-LOCAL_MODULE := libcorkscrew_test
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_EXECUTABLE)
-
-endif # TARGET_IS_64_BIT == false
-
-
-ifeq ($(HOST_OS)-$(HOST_ARCH),linux-x86)
-
-# Build libcorkscrew.
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES += $(generic_src_files) $(x86_src_files)
-LOCAL_CFLAGS += -DCORKSCREW_HAVE_ARCH
-LOCAL_STATIC_LIBRARIES += libcutils liblog
-LOCAL_LDLIBS += -ldl
-ifeq ($(HOST_OS),linux)
-  LOCAL_SHARED_LIBRARIES += libgccdemangle # TODO: is this even needed on Linux?
-  LOCAL_LDLIBS += -lrt
-endif
-LOCAL_CFLAGS += -std=gnu99 -Werror -Wno-unused-parameter
-LOCAL_MODULE := libcorkscrew
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_HOST_SHARED_LIBRARY)
-
-# Build test.
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := test.cpp
-LOCAL_CFLAGS += -Werror
-LOCAL_SHARED_LIBRARIES := libcorkscrew
-LOCAL_MODULE := libcorkscrew_test
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_HOST_EXECUTABLE)
-
-endif # $(HOST_OS)-$(HOST_ARCH) == linux-x86
diff --git a/libcorkscrew/MODULE_LICENSE_APACHE2 b/libcorkscrew/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/libcorkscrew/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/libcorkscrew/NOTICE b/libcorkscrew/NOTICE
deleted file mode 100644
index becc120..0000000
--- a/libcorkscrew/NOTICE
+++ /dev/null
@@ -1,190 +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.
-
-   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/libcorkscrew/arch-arm/backtrace-arm.c b/libcorkscrew/arch-arm/backtrace-arm.c
deleted file mode 100644
index 751efbf..0000000
--- a/libcorkscrew/arch-arm/backtrace-arm.c
+++ /dev/null
@@ -1,589 +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.
- */
-
-/*
- * Backtracing functions for ARM.
- *
- * This implementation uses the exception unwinding tables provided by
- * the compiler to unwind call frames.  Refer to the ARM Exception Handling ABI
- * documentation (EHABI) for more details about what's going on here.
- *
- * An ELF binary may contain an EXIDX section that provides an index to
- * the exception handling table of each function, sorted by program
- * counter address.
- *
- * This implementation also supports unwinding other processes via ptrace().
- * In that case, the EXIDX section is found by reading the ELF section table
- * structures using ptrace().
- *
- * Because the tables are used for exception handling, it can happen that
- * a given function will not have an exception handling table.  In particular,
- * exceptions are assumed to only ever be thrown at call sites.  Therefore,
- * by definition leaf functions will not have exception handling tables.
- * This may make unwinding impossible in some cases although we can still get
- * some idea of the call stack by examining the PC and LR registers.
- *
- * As we are only interested in backtrace information, we do not need
- * to perform all of the work of unwinding such as restoring register
- * state and running cleanup functions.  Unwinding is performed virtually on
- * an abstract machine context consisting of just the ARM core registers.
- * Furthermore, we do not run generic "personality functions" because
- * we may not be in a position to execute arbitrary code, especially if
- * we are running in a signal handler or using ptrace()!
- */
-
-#define LOG_TAG "Corkscrew"
-//#define LOG_NDEBUG 0
-
-#include "../backtrace-arch.h"
-#include "../backtrace-helper.h"
-#include "../ptrace-arch.h"
-#include <corkscrew/ptrace.h>
-
-#include <stdlib.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/ptrace.h>
-#include <elf.h>
-#include <cutils/log.h>
-
-#include <ucontext.h>
-
-/* Unwind state. */
-typedef struct {
-    uint32_t gregs[16];
-} unwind_state_t;
-
-static const int R_SP = 13;
-static const int R_LR = 14;
-static const int R_PC = 15;
-
-/* Special EXIDX value that indicates that a frame cannot be unwound. */
-static const uint32_t EXIDX_CANTUNWIND = 1;
-
-/* Get the EXIDX section start and size for the module that contains a
- * given program counter address.
- *
- * When the executable is statically linked, the EXIDX section can be
- * accessed by querying the values of the __exidx_start and __exidx_end
- * symbols.
- *
- * When the executable is dynamically linked, the linker exports a function
- * called dl_unwind_find_exidx that obtains the EXIDX section for a given
- * absolute program counter address.
- *
- * Bionic exports a helpful function called __gnu_Unwind_Find_exidx that
- * handles both cases, so we use that here.
- */
-typedef long unsigned int* _Unwind_Ptr;
-extern _Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr pc, int *pcount);
-
-static uintptr_t find_exidx(uintptr_t pc, size_t* out_exidx_size) {
-    int count;
-    uintptr_t start = (uintptr_t)__gnu_Unwind_Find_exidx((_Unwind_Ptr)pc, &count);
-    *out_exidx_size = count;
-    return start;
-}
-
-/* Transforms a 31-bit place-relative offset to an absolute address.
- * We assume the most significant bit is clear. */
-static uintptr_t prel_to_absolute(uintptr_t place, uint32_t prel_offset) {
-    return place + (((int32_t)(prel_offset << 1)) >> 1);
-}
-
-static uintptr_t get_exception_handler(const memory_t* memory,
-        const map_info_t* map_info_list, uintptr_t pc) {
-    if (!pc) {
-        ALOGV("get_exception_handler: pc is zero, no handler");
-        return 0;
-    }
-
-    uintptr_t exidx_start;
-    size_t exidx_size;
-    const map_info_t* mi;
-    if (memory->tid < 0) {
-        mi = NULL;
-        exidx_start = find_exidx(pc, &exidx_size);
-    } else {
-        mi = find_map_info(map_info_list, pc);
-        if (mi && mi->data) {
-            const map_info_data_t* data = (const map_info_data_t*)mi->data;
-            exidx_start = data->exidx_start;
-            exidx_size = data->exidx_size;
-        } else {
-            exidx_start = 0;
-            exidx_size = 0;
-        }
-    }
-
-    uintptr_t handler = 0;
-    int32_t handler_index = -1;
-    if (exidx_start) {
-        uint32_t low = 0;
-        uint32_t high = exidx_size;
-        while (low < high) {
-            uint32_t index = (low + high) / 2;
-            uintptr_t entry = exidx_start + index * 8;
-            uint32_t entry_prel_pc;
-            ALOGV("XXX low=%u, high=%u, index=%u", low, high, index);
-            if (!try_get_word(memory, entry, &entry_prel_pc)) {
-                break;
-            }
-            uintptr_t entry_pc = prel_to_absolute(entry, entry_prel_pc);
-            ALOGV("XXX entry_pc=0x%08x", entry_pc);
-            if (pc < entry_pc) {
-                high = index;
-                continue;
-            }
-            if (index + 1 < exidx_size) {
-                uintptr_t next_entry = entry + 8;
-                uint32_t next_entry_prel_pc;
-                if (!try_get_word(memory, next_entry, &next_entry_prel_pc)) {
-                    break;
-                }
-                uintptr_t next_entry_pc = prel_to_absolute(next_entry, next_entry_prel_pc);
-                ALOGV("XXX next_entry_pc=0x%08x", next_entry_pc);
-                if (pc >= next_entry_pc) {
-                    low = index + 1;
-                    continue;
-                }
-            }
-
-            uintptr_t entry_handler_ptr = entry + 4;
-            uint32_t entry_handler;
-            if (!try_get_word(memory, entry_handler_ptr, &entry_handler)) {
-                break;
-            }
-            if (entry_handler & (1L << 31)) {
-                handler = entry_handler_ptr; // in-place handler data
-            } else if (entry_handler != EXIDX_CANTUNWIND) {
-                handler = prel_to_absolute(entry_handler_ptr, entry_handler);
-            }
-            handler_index = index;
-            break;
-        }
-    }
-    if (mi) {
-        ALOGV("get_exception_handler: pc=0x%08x, module='%s', module_start=0x%08x, "
-                "exidx_start=0x%08x, exidx_size=%d, handler=0x%08x, handler_index=%d",
-                pc, mi->name, mi->start, exidx_start, exidx_size, handler, handler_index);
-    } else {
-        ALOGV("get_exception_handler: pc=0x%08x, "
-                "exidx_start=0x%08x, exidx_size=%d, handler=0x%08x, handler_index=%d",
-                pc, exidx_start, exidx_size, handler, handler_index);
-    }
-    return handler;
-}
-
-typedef struct {
-    uintptr_t ptr;
-    uint32_t word;
-} byte_stream_t;
-
-static bool try_next_byte(const memory_t* memory, byte_stream_t* stream, uint8_t* out_value) {
-    uint8_t result;
-    switch (stream->ptr & 3) {
-    case 0:
-        if (!try_get_word(memory, stream->ptr, &stream->word)) {
-            *out_value = 0;
-            return false;
-        }
-        *out_value = stream->word >> 24;
-        break;
-
-    case 1:
-        *out_value = stream->word >> 16;
-        break;
-
-    case 2:
-        *out_value = stream->word >> 8;
-        break;
-
-    default:
-        *out_value = stream->word;
-        break;
-    }
-
-    ALOGV("next_byte: ptr=0x%08x, value=0x%02x", stream->ptr, *out_value);
-    stream->ptr += 1;
-    return true;
-}
-
-static void set_reg(unwind_state_t* state, uint32_t reg, uint32_t value) {
-    ALOGV("set_reg: reg=%d, value=0x%08x", reg, value);
-    state->gregs[reg] = value;
-}
-
-static bool try_pop_registers(const memory_t* memory, unwind_state_t* state, uint32_t mask) {
-    uint32_t sp = state->gregs[R_SP];
-    bool sp_updated = false;
-    for (int i = 0; i < 16; i++) {
-        if (mask & (1 << i)) {
-            uint32_t value;
-            if (!try_get_word(memory, sp, &value)) {
-                return false;
-            }
-            if (i == R_SP) {
-                sp_updated = true;
-            }
-            set_reg(state, i, value);
-            sp += 4;
-        }
-    }
-    if (!sp_updated) {
-        set_reg(state, R_SP, sp);
-    }
-    return true;
-}
-
-/* Executes a built-in personality routine as defined in the EHABI.
- * Returns true if unwinding should continue.
- *
- * The data for the built-in personality routines consists of a sequence
- * of unwinding instructions, followed by a sequence of scope descriptors,
- * each of which has a length and offset encoded using 16-bit or 32-bit
- * values.
- *
- * We only care about the unwinding instructions.  They specify the
- * operations of an abstract machine whose purpose is to transform the
- * virtual register state (including the stack pointer) such that
- * the call frame is unwound and the PC register points to the call site.
- */
-static bool execute_personality_routine(const memory_t* memory,
-        unwind_state_t* state, byte_stream_t* stream, int pr_index) {
-    size_t size;
-    switch (pr_index) {
-    case 0: // Personality routine #0, short frame, descriptors have 16-bit scope.
-        size = 3;
-        break;
-    case 1: // Personality routine #1, long frame, descriptors have 16-bit scope.
-    case 2: { // Personality routine #2, long frame, descriptors have 32-bit scope.
-        uint8_t size_byte;
-        if (!try_next_byte(memory, stream, &size_byte)) {
-            return false;
-        }
-        size = (uint32_t)size_byte * sizeof(uint32_t) + 2;
-        break;
-    }
-    default: // Unknown personality routine.  Stop here.
-        return false;
-    }
-
-    bool pc_was_set = false;
-    while (size--) {
-        uint8_t op;
-        if (!try_next_byte(memory, stream, &op)) {
-            return false;
-        }
-        if ((op & 0xc0) == 0x00) {
-            // "vsp = vsp + (xxxxxx << 2) + 4"
-            set_reg(state, R_SP, state->gregs[R_SP] + ((op & 0x3f) << 2) + 4);
-        } else if ((op & 0xc0) == 0x40) {
-            // "vsp = vsp - (xxxxxx << 2) - 4"
-            set_reg(state, R_SP, state->gregs[R_SP] - ((op & 0x3f) << 2) - 4);
-        } else if ((op & 0xf0) == 0x80) {
-            uint8_t op2;
-            if (!(size--) || !try_next_byte(memory, stream, &op2)) {
-                return false;
-            }
-            uint32_t mask = (((uint32_t)op & 0x0f) << 12) | ((uint32_t)op2 << 4);
-            if (mask) {
-                // "Pop up to 12 integer registers under masks {r15-r12}, {r11-r4}"
-                if (!try_pop_registers(memory, state, mask)) {
-                    return false;
-                }
-                if (mask & (1 << R_PC)) {
-                    pc_was_set = true;
-                }
-            } else {
-                // "Refuse to unwind"
-                return false;
-            }
-        } else if ((op & 0xf0) == 0x90) {
-            if (op != 0x9d && op != 0x9f) {
-                // "Set vsp = r[nnnn]"
-                set_reg(state, R_SP, state->gregs[op & 0x0f]);
-            } else {
-                // "Reserved as prefix for ARM register to register moves"
-                // "Reserved as prefix for Intel Wireless MMX register to register moves"
-                return false;
-            }
-        } else if ((op & 0xf8) == 0xa0) {
-            // "Pop r4-r[4+nnn]"
-            uint32_t mask = (0x0ff0 >> (7 - (op & 0x07))) & 0x0ff0;
-            if (!try_pop_registers(memory, state, mask)) {
-                return false;
-            }
-        } else if ((op & 0xf8) == 0xa8) {
-            // "Pop r4-r[4+nnn], r14"
-            uint32_t mask = ((0x0ff0 >> (7 - (op & 0x07))) & 0x0ff0) | 0x4000;
-            if (!try_pop_registers(memory, state, mask)) {
-                return false;
-            }
-        } else if (op == 0xb0) {
-            // "Finish"
-            break;
-        } else if (op == 0xb1) {
-            uint8_t op2;
-            if (!(size--) || !try_next_byte(memory, stream, &op2)) {
-                return false;
-            }
-            if (op2 != 0x00 && (op2 & 0xf0) == 0x00) {
-                // "Pop integer registers under mask {r3, r2, r1, r0}"
-                if (!try_pop_registers(memory, state, op2)) {
-                    return false;
-                }
-            } else {
-                // "Spare"
-                return false;
-            }
-        } else if (op == 0xb2) {
-            // "vsp = vsp + 0x204 + (uleb128 << 2)"
-            uint32_t value = 0;
-            uint32_t shift = 0;
-            uint8_t op2;
-            do {
-                if (!(size--) || !try_next_byte(memory, stream, &op2)) {
-                    return false;
-                }
-                value |= (op2 & 0x7f) << shift;
-                shift += 7;
-            } while (op2 & 0x80);
-            set_reg(state, R_SP, state->gregs[R_SP] + (value << 2) + 0x204);
-        } else if (op == 0xb3) {
-            // "Pop VFP double-precision registers D[ssss]-D[ssss+cccc] saved (as if) by FSTMFDX"
-            uint8_t op2;
-            if (!(size--) || !try_next_byte(memory, stream, &op2)) {
-                return false;
-            }
-            set_reg(state, R_SP, state->gregs[R_SP] + (uint32_t)(op2 & 0x0f) * 8 + 12);
-        } else if ((op & 0xf8) == 0xb8) {
-            // "Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by FSTMFDX"
-            set_reg(state, R_SP, state->gregs[R_SP] + (uint32_t)(op & 0x07) * 8 + 12);
-        } else if ((op & 0xf8) == 0xc0) {
-            // "Intel Wireless MMX pop wR[10]-wR[10+nnn]"
-            set_reg(state, R_SP, state->gregs[R_SP] + (uint32_t)(op & 0x07) * 8 + 8);
-        } else if (op == 0xc6) {
-            // "Intel Wireless MMX pop wR[ssss]-wR[ssss+cccc]"
-            uint8_t op2;
-            if (!(size--) || !try_next_byte(memory, stream, &op2)) {
-                return false;
-            }
-            set_reg(state, R_SP, state->gregs[R_SP] + (uint32_t)(op2 & 0x0f) * 8 + 8);
-        } else if (op == 0xc7) {
-            uint8_t op2;
-            if (!(size--) || !try_next_byte(memory, stream, &op2)) {
-                return false;
-            }
-            if (op2 != 0x00 && (op2 & 0xf0) == 0x00) {
-                // "Intel Wireless MMX pop wCGR registers under mask {wCGR3,2,1,0}"
-                set_reg(state, R_SP, state->gregs[R_SP] + __builtin_popcount(op2) * 4);
-            } else {
-                // "Spare"
-                return false;
-            }
-        } else if (op == 0xc8) {
-            // "Pop VFP double precision registers D[16+ssss]-D[16+ssss+cccc]
-            // saved (as if) by FSTMFD"
-            uint8_t op2;
-            if (!(size--) || !try_next_byte(memory, stream, &op2)) {
-                return false;
-            }
-            set_reg(state, R_SP, state->gregs[R_SP] + (uint32_t)(op2 & 0x0f) * 8 + 8);
-        } else if (op == 0xc9) {
-            // "Pop VFP double precision registers D[ssss]-D[ssss+cccc] saved (as if) by FSTMFDD"
-            uint8_t op2;
-            if (!(size--) || !try_next_byte(memory, stream, &op2)) {
-                return false;
-            }
-            set_reg(state, R_SP, state->gregs[R_SP] + (uint32_t)(op2 & 0x0f) * 8 + 8);
-        } else if ((op == 0xf8) == 0xd0) {
-            // "Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by FSTMFDD"
-            set_reg(state, R_SP, state->gregs[R_SP] + (uint32_t)(op & 0x07) * 8 + 8);
-        } else {
-            // "Spare"
-            return false;
-        }
-    }
-    if (!pc_was_set) {
-        set_reg(state, R_PC, state->gregs[R_LR]);
-    }
-    return true;
-}
-
-static bool try_get_half_word(const memory_t* memory, uint32_t pc, uint16_t* out_value) {
-    uint32_t word;
-    if (try_get_word(memory, pc & ~2, &word)) {
-        *out_value = pc & 2 ? word >> 16 : word & 0xffff;
-        return true;
-    }
-    return false;
-}
-
-uintptr_t rewind_pc_arch(const memory_t* memory, uintptr_t pc) {
-    if (pc & 1) {
-        /* Thumb mode - need to check whether the bl(x) has long offset or not.
-         * Examples:
-         *
-         * arm blx in the middle of thumb:
-         * 187ae:       2300            movs    r3, #0
-         * 187b0:       f7fe ee1c       blx     173ec
-         * 187b4:       2c00            cmp     r4, #0
-         *
-         * arm bl in the middle of thumb:
-         * 187d8:       1c20            adds    r0, r4, #0
-         * 187da:       f136 fd15       bl      14f208
-         * 187de:       2800            cmp     r0, #0
-         *
-         * pure thumb:
-         * 18894:       189b            adds    r3, r3, r2
-         * 18896:       4798            blx     r3
-         * 18898:       b001            add     sp, #4
-         */
-        uint16_t prev1, prev2;
-        if (try_get_half_word(memory, pc - 5, &prev1)
-            && ((prev1 & 0xf000) == 0xf000)
-            && try_get_half_word(memory, pc - 3, &prev2)
-            && ((prev2 & 0xe000) == 0xe000)) {
-            pc -= 4; // long offset
-        } else {
-            pc -= 2;
-        }
-    } else {
-        /* ARM mode, all instructions are 32bit.  Yay! */
-        pc -= 4;
-    }
-    return pc;
-}
-
-static ssize_t unwind_backtrace_common(const memory_t* memory,
-        const map_info_t* map_info_list,
-        unwind_state_t* state, backtrace_frame_t* backtrace,
-        size_t ignore_depth, size_t max_depth) {
-    size_t ignored_frames = 0;
-    size_t returned_frames = 0;
-
-    for (size_t index = 0; returned_frames < max_depth; index++) {
-        uintptr_t pc = index ? rewind_pc_arch(memory, state->gregs[R_PC])
-                : state->gregs[R_PC];
-        backtrace_frame_t* frame = add_backtrace_entry(pc,
-                backtrace, ignore_depth, max_depth, &ignored_frames, &returned_frames);
-        if (frame) {
-            frame->stack_top = state->gregs[R_SP];
-        }
-
-        uintptr_t handler = get_exception_handler(memory, map_info_list, pc);
-        if (!handler) {
-            // If there is no handler for the PC and this is the first frame,
-            // then the program may have branched to an invalid address.
-            // Try starting from the LR instead, otherwise stop unwinding.
-            if (index == 0 && state->gregs[R_LR]
-                    && state->gregs[R_LR] != state->gregs[R_PC]) {
-                set_reg(state, R_PC, state->gregs[R_LR]);
-                continue;
-            } else {
-                break;
-            }
-        }
-
-        byte_stream_t stream;
-        stream.ptr = handler;
-        uint8_t pr;
-        if (!try_next_byte(memory, &stream, &pr)) {
-            break;
-        }
-        if ((pr & 0xf0) != 0x80) {
-            // The first word is a place-relative pointer to a generic personality
-            // routine function.  We don't support invoking such functions, so stop here.
-            break;
-        }
-
-        // The first byte indicates the personality routine to execute.
-        // Following bytes provide instructions to the personality routine.
-        if (!execute_personality_routine(memory, state, &stream, pr & 0x0f)) {
-            break;
-        }
-        if (frame && state->gregs[R_SP] > frame->stack_top) {
-            frame->stack_size = state->gregs[R_SP] - frame->stack_top;
-        }
-        if (!state->gregs[R_PC]) {
-            break;
-        }
-    }
-
-    // Ran out of frames that we could unwind using handlers.
-    // Add a final entry for the LR if it looks sane and call it good.
-    if (returned_frames < max_depth
-            && state->gregs[R_LR]
-            && state->gregs[R_LR] != state->gregs[R_PC]
-            && is_executable_map(map_info_list, state->gregs[R_LR])) {
-        // We don't know where the stack for this extra frame starts so we
-        // don't return any stack information for it.
-        add_backtrace_entry(rewind_pc_arch(memory, state->gregs[R_LR]),
-                backtrace, ignore_depth, max_depth, &ignored_frames, &returned_frames);
-    }
-    return returned_frames;
-}
-
-ssize_t unwind_backtrace_signal_arch(siginfo_t* siginfo, void* sigcontext,
-        const map_info_t* map_info_list,
-        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) {
-    const ucontext_t* uc = (const ucontext_t*)sigcontext;
-
-    unwind_state_t state;
-
-    state.gregs[0] = uc->uc_mcontext.arm_r0;
-    state.gregs[1] = uc->uc_mcontext.arm_r1;
-    state.gregs[2] = uc->uc_mcontext.arm_r2;
-    state.gregs[3] = uc->uc_mcontext.arm_r3;
-    state.gregs[4] = uc->uc_mcontext.arm_r4;
-    state.gregs[5] = uc->uc_mcontext.arm_r5;
-    state.gregs[6] = uc->uc_mcontext.arm_r6;
-    state.gregs[7] = uc->uc_mcontext.arm_r7;
-    state.gregs[8] = uc->uc_mcontext.arm_r8;
-    state.gregs[9] = uc->uc_mcontext.arm_r9;
-    state.gregs[10] = uc->uc_mcontext.arm_r10;
-    state.gregs[11] = uc->uc_mcontext.arm_fp;
-    state.gregs[12] = uc->uc_mcontext.arm_ip;
-    state.gregs[13] = uc->uc_mcontext.arm_sp;
-    state.gregs[14] = uc->uc_mcontext.arm_lr;
-    state.gregs[15] = uc->uc_mcontext.arm_pc;
-
-    memory_t memory;
-    init_memory(&memory, map_info_list);
-    return unwind_backtrace_common(&memory, map_info_list, &state,
-            backtrace, ignore_depth, max_depth);
-}
-
-ssize_t unwind_backtrace_ptrace_arch(pid_t tid, const ptrace_context_t* context,
-        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) {
-    struct pt_regs regs;
-    if (ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
-        return -1;
-    }
-
-    unwind_state_t state;
-    for (int i = 0; i < 16; i++) {
-        state.gregs[i] = regs.uregs[i];
-    }
-
-    memory_t memory;
-    init_memory_ptrace(&memory, tid);
-    return unwind_backtrace_common(&memory, context->map_info_list, &state,
-            backtrace, ignore_depth, max_depth);
-}
diff --git a/libcorkscrew/arch-arm/ptrace-arm.c b/libcorkscrew/arch-arm/ptrace-arm.c
deleted file mode 100644
index a50844e..0000000
--- a/libcorkscrew/arch-arm/ptrace-arm.c
+++ /dev/null
@@ -1,73 +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.
- */
-
-#define LOG_TAG "Corkscrew"
-//#define LOG_NDEBUG 0
-
-#include "../ptrace-arch.h"
-
-#include <elf.h>
-#include <cutils/log.h>
-
-#ifndef PT_ARM_EXIDX
-#define PT_ARM_EXIDX 0x70000001
-#endif
-
-static void load_exidx_header(pid_t pid, map_info_t* mi,
-        uintptr_t* out_exidx_start, size_t* out_exidx_size) {
-    uint32_t elf_phoff;
-    uint32_t elf_phentsize_ehsize;
-    uint32_t elf_shentsize_phnum;
-    if (try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_phoff), &elf_phoff)
-            && try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_ehsize),
-                    &elf_phentsize_ehsize)
-            && try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_phnum),
-                    &elf_shentsize_phnum)) {
-        uint32_t elf_phentsize = elf_phentsize_ehsize >> 16;
-        uint32_t elf_phnum = elf_shentsize_phnum & 0xffff;
-        for (uint32_t i = 0; i < elf_phnum; i++) {
-            uintptr_t elf_phdr = mi->start + elf_phoff + i * elf_phentsize;
-            uint32_t elf_phdr_type;
-            if (!try_get_word_ptrace(pid, elf_phdr + offsetof(Elf32_Phdr, p_type), &elf_phdr_type)) {
-                break;
-            }
-            if (elf_phdr_type == PT_ARM_EXIDX) {
-                uint32_t elf_phdr_offset;
-                uint32_t elf_phdr_filesz;
-                if (!try_get_word_ptrace(pid, elf_phdr + offsetof(Elf32_Phdr, p_offset),
-                        &elf_phdr_offset)
-                        || !try_get_word_ptrace(pid, elf_phdr + offsetof(Elf32_Phdr, p_filesz),
-                                &elf_phdr_filesz)) {
-                    break;
-                }
-                *out_exidx_start = mi->start + elf_phdr_offset;
-                *out_exidx_size = elf_phdr_filesz / 8;
-                ALOGV("Parsed EXIDX header info for %s: start=0x%08x, size=%d", mi->name,
-                        *out_exidx_start, *out_exidx_size);
-                return;
-            }
-        }
-    }
-    *out_exidx_start = 0;
-    *out_exidx_size = 0;
-}
-
-void load_ptrace_map_info_data_arch(pid_t pid, map_info_t* mi, map_info_data_t* data) {
-    load_exidx_header(pid, mi, &data->exidx_start, &data->exidx_size);
-}
-
-void free_ptrace_map_info_data_arch(map_info_t* mi, map_info_data_t* data) {
-}
diff --git a/libcorkscrew/arch-mips/backtrace-mips.c b/libcorkscrew/arch-mips/backtrace-mips.c
deleted file mode 100644
index 832fb86..0000000
--- a/libcorkscrew/arch-mips/backtrace-mips.c
+++ /dev/null
@@ -1,901 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-/*
- * Backtracing functions for mips
- */
-
-#define LOG_TAG "Corkscrew"
-//#define LOG_NDEBUG 0
-
-#include "../backtrace-arch.h"
-#include "../backtrace-helper.h"
-#include "../ptrace-arch.h"
-#include <corkscrew/ptrace.h>
-#include "dwarf.h"
-
-#include <stdlib.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <limits.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/ptrace.h>
-#include <cutils/log.h>
-
-#include <sys/ucontext.h>
-
-/* For PTRACE_GETREGS */
-typedef struct {
-    uint64_t regs[32];
-    uint64_t lo;
-    uint64_t hi;
-    uint64_t epc;
-    uint64_t badvaddr;
-    uint64_t status;
-    uint64_t cause;
-} user_regs_struct;
-
-enum {
-    REG_ZERO = 0, REG_AT, REG_V0, REG_V1,
-    REG_A0, REG_A1, REG_A2, REG_A3,
-    REG_T0, REG_T1, REG_T2, REG_T3,
-    REG_T4, REG_T5, REG_T6, REG_T7,
-    REG_S0, REG_S1, REG_S2, REG_S3,
-    REG_S4, REG_S5, REG_S6, REG_S7,
-    REG_T8, REG_T9, REG_K0, REG_K1,
-    REG_GP, REG_SP, REG_S8, REG_RA,
-};
-
-
-/* Unwind state. */
-typedef struct {
-    uint32_t reg[DWARF_REGISTERS];
-} unwind_state_t;
-
-uintptr_t rewind_pc_arch(const memory_t* memory __attribute__((unused)), uintptr_t pc) {
-    if (pc == 0)
-        return pc;
-    if ((pc & 1) == 0)
-        return pc-8;            /* jal/bal/jalr + branch delay slot */
-    return pc;
-}
-
-/* Read byte through 4 byte cache. Usually we read byte by byte and updating cursor. */
-static bool try_get_byte(const memory_t* memory, uintptr_t ptr, uint8_t* out_value, uint32_t* cursor) {
-    static uintptr_t lastptr;
-    static uint32_t buf;
-
-    ptr += *cursor;
-
-    if (ptr < lastptr || lastptr + 3 < ptr) {
-        lastptr = (ptr >> 2) << 2;
-        if (!try_get_word(memory, lastptr, &buf)) {
-            return false;
-        }
-    }
-    *out_value = (uint8_t)((buf >> ((ptr & 3) * 8)) & 0xff);
-    ++*cursor;
-    return true;
-}
-
-/* Getting X bytes. 4 is maximum for now. */
-static bool try_get_xbytes(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint8_t bytes, uint32_t* cursor) {
-    uint32_t data = 0;
-    if (bytes > 4) {
-        ALOGE("can't read more than 4 bytes, trying to read %d", bytes);
-        return false;
-    }
-    for (int i = 0; i < bytes; i++) {
-        uint8_t buf;
-        if (!try_get_byte(memory, ptr, &buf, cursor)) {
-            return false;
-        }
-        data |= (uint32_t)buf << (i * 8);
-    }
-    *out_value = data;
-    return true;
-}
-
-/* Reads signed/unsigned LEB128 encoded data. From 1 to 4 bytes. */
-static bool try_get_leb128(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint32_t* cursor, bool sign_extend) {
-    uint8_t buf = 0;
-    uint32_t val = 0;
-    uint8_t c = 0;
-    do {
-        if (!try_get_byte(memory, ptr, &buf, cursor)) {
-            return false;
-        }
-        val |= ((uint32_t)buf & 0x7f) << (c * 7);
-        c++;
-    } while (buf & 0x80 && (c * 7) <= 32);
-    if (c * 7 > 32) {
-        ALOGE("%s: data exceeds expected 4 bytes maximum", __FUNCTION__);
-        return false;
-    }
-    if (sign_extend) {
-        if (buf & 0x40) {
-            val |= ((uint32_t)-1 << (c * 7));
-        }
-    }
-    *out_value = val;
-    return true;
-}
-
-/* Reads signed LEB128 encoded data. From 1 to 4 bytes. */
-static bool try_get_sleb128(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint32_t* cursor) {
-    return try_get_leb128(memory, ptr, out_value, cursor, true);
-}
-
-/* Reads unsigned LEB128 encoded data. From 1 to 4 bytes. */
-static bool try_get_uleb128(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint32_t* cursor) {
-    return try_get_leb128(memory, ptr, out_value, cursor, false);
-}
-
-/* Getting data encoded by dwarf encodings. */
-static bool read_dwarf(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint8_t encoding, uint32_t* cursor) {
-    uint32_t data = 0;
-    bool issigned = true;
-    uintptr_t addr = ptr + *cursor;
-    /* Lower 4 bits is data type/size */
-    /* TODO: add more encodings if it becomes necessary */
-    switch (encoding & 0xf) {
-    case DW_EH_PE_absptr:
-        if (!try_get_xbytes(memory, ptr, &data, 4, cursor)) {
-            return false;
-        }
-        *out_value = data;
-        return true;
-    case DW_EH_PE_udata4:
-        issigned = false;
-    case DW_EH_PE_sdata4:
-        if (!try_get_xbytes(memory, ptr, &data, 4, cursor)) {
-            return false;
-        }
-        break;
-    default:
-        ALOGE("unrecognized dwarf lower part encoding: 0x%x", encoding);
-        return false;
-    }
-    /* Higher 4 bits is modifier */
-    /* TODO: add more encodings if it becomes necessary */
-    switch (encoding & 0xf0) {
-    case 0:
-        *out_value = data;
-        break;
-    case DW_EH_PE_pcrel:
-        if (issigned) {
-            *out_value = addr + (int32_t)data;
-        } else {
-            *out_value = addr + data;
-        }
-        break;
-        /* Assuming ptr is correct base to calculate datarel */
-    case DW_EH_PE_datarel:
-        if (issigned) {
-            *out_value = ptr + (int32_t)data;
-        } else {
-            *out_value = ptr + data;
-        }
-        break;
-    default:
-        ALOGE("unrecognized dwarf higher part encoding: 0x%x", encoding);
-        return false;
-    }
-    return true;
-}
-
-/* Having PC find corresponding FDE by reading .eh_frame_hdr section data. */
-static uintptr_t find_fde(const memory_t* memory,
-                          const map_info_t* map_info_list, uintptr_t pc) {
-    if (!pc) {
-        ALOGV("find_fde: pc is zero, no eh_frame");
-        return 0;
-    }
-    const map_info_t* mi = find_map_info(map_info_list, pc);
-    if (!mi) {
-        ALOGV("find_fde: no map info for pc:0x%x", pc);
-        return 0;
-    }
-    const map_info_data_t* midata = mi->data;
-    if (!midata) {
-        ALOGV("find_fde: no eh_frame_hdr for map: start=0x%x, end=0x%x", mi->start, mi->end);
-        return 0;
-    }
-
-    eh_frame_hdr_info_t eh_hdr_info;
-    memset(&eh_hdr_info, 0, sizeof(eh_frame_hdr_info_t));
-
-    /* Getting the first word of eh_frame_hdr:
-       1st byte is version;
-       2nd byte is encoding of pointer to eh_frames;
-       3rd byte is encoding of count of FDEs in lookup table;
-       4th byte is encoding of lookup table entries.
-    */
-    uintptr_t eh_frame_hdr = midata->eh_frame_hdr;
-    uint32_t c = 0;
-    if (!try_get_byte(memory, eh_frame_hdr, &eh_hdr_info.version, &c)) return 0;
-    if (!try_get_byte(memory, eh_frame_hdr, &eh_hdr_info.eh_frame_ptr_enc, &c)) return 0;
-    if (!try_get_byte(memory, eh_frame_hdr, &eh_hdr_info.fde_count_enc, &c)) return 0;
-    if (!try_get_byte(memory, eh_frame_hdr, &eh_hdr_info.fde_table_enc, &c)) return 0;
-
-    /* TODO: 3rd byte can be DW_EH_PE_omit, that means no lookup table available and we should
-       try to parse eh_frame instead. Not sure how often it may occur, skipping now.
-    */
-    if (eh_hdr_info.version != 1) {
-        ALOGV("find_fde: eh_frame_hdr version %d is not supported", eh_hdr_info.version);
-        return 0;
-    }
-    /* Getting the data:
-       2nd word is eh_frame pointer (normally not used, because lookup table has all we need);
-       3rd word is count of FDEs in the lookup table;
-       starting from 4 word there is FDE lookup table (pairs of PC and FDE pointer) sorted by PC;
-    */
-    if (!read_dwarf(memory, eh_frame_hdr, &eh_hdr_info.eh_frame_ptr, eh_hdr_info.eh_frame_ptr_enc, &c)) return 0;
-    if (!read_dwarf(memory, eh_frame_hdr, &eh_hdr_info.fde_count, eh_hdr_info.fde_count_enc, &c)) return 0;
-    ALOGV("find_fde: found %d FDEs", eh_hdr_info.fde_count);
-
-    int32_t low = 0;
-    int32_t high = eh_hdr_info.fde_count;
-    uintptr_t start = 0;
-    uintptr_t fde = 0;
-    /* eh_frame_hdr + c points to lookup table at this point. */
-    while (low <= high) {
-        uint32_t mid = (high + low)/2;
-        uint32_t entry = c + mid * 8;
-        if (!read_dwarf(memory, eh_frame_hdr, &start, eh_hdr_info.fde_table_enc, &entry)) return 0;
-        if (pc <= start) {
-            high = mid - 1;
-        } else {
-            low = mid + 1;
-        }
-    }
-    /* Value found is at high. */
-    if (high < 0) {
-        ALOGV("find_fde: pc %x is out of FDE bounds: %x", pc, start);
-        return 0;
-    }
-    c += high * 8;
-    if (!read_dwarf(memory, eh_frame_hdr, &start, eh_hdr_info.fde_table_enc, &c)) return 0;
-    if (!read_dwarf(memory, eh_frame_hdr, &fde, eh_hdr_info.fde_table_enc, &c)) return 0;
-    ALOGV("pc 0x%x, ENTRY %d: start=0x%x, fde=0x%x", pc, high, start, fde);
-    return fde;
-}
-
-/* Execute single dwarf instruction and update dwarf state accordingly. */
-static bool execute_dwarf(const memory_t* memory, uintptr_t ptr, cie_info_t* cie_info,
-                          dwarf_state_t* dstate, uint32_t* cursor,
-                          dwarf_state_t* stack, uint8_t* stack_ptr) {
-    uint8_t inst;
-    uint8_t op = 0;
-
-    if (!try_get_byte(memory, ptr, &inst, cursor)) {
-        return false;
-    }
-    ALOGV("DW_CFA inst: 0x%x", inst);
-
-    /* For some instructions upper 2 bits is opcode and lower 6 bits is operand. See dwarf-2.0 7.23. */
-    if (inst & 0xc0) {
-        op = inst & 0x3f;
-        inst &= 0xc0;
-    }
-
-    switch ((dwarf_CFA)inst) {
-        uint32_t reg = 0;
-        uint32_t offset = 0;
-    case DW_CFA_advance_loc:
-        dstate->loc += op * cie_info->code_align;
-        ALOGV("DW_CFA_advance_loc: %d to 0x%x", op, dstate->loc);
-        break;
-    case DW_CFA_offset:
-        if (!try_get_uleb128(memory, ptr, &offset, cursor)) return false;
-        dstate->regs[op].rule = 'o';
-        dstate->regs[op].value = offset * cie_info->data_align;
-        ALOGV("DW_CFA_offset: r%d = o(%d)", op, dstate->regs[op].value);
-        break;
-    case DW_CFA_restore:
-        dstate->regs[op].rule = stack->regs[op].rule;
-        dstate->regs[op].value = stack->regs[op].value;
-        ALOGV("DW_CFA_restore: r%d = %c(%d)", op, dstate->regs[op].rule, dstate->regs[op].value);
-        break;
-    case DW_CFA_nop:
-        break;
-    case DW_CFA_set_loc: // probably we don't have it on mips.
-        if (!try_get_xbytes(memory, ptr, &offset, 4, cursor)) return false;
-        if (offset < dstate->loc) {
-            ALOGE("DW_CFA_set_loc: attempt to move location backward");
-            return false;
-        }
-        dstate->loc = offset * cie_info->code_align;
-        ALOGV("DW_CFA_set_loc: %d to 0x%x", offset * cie_info->code_align, dstate->loc);
-        break;
-    case DW_CFA_advance_loc1:
-        if (!try_get_byte(memory, ptr, (uint8_t*)&offset, cursor)) return false;
-        dstate->loc += (uint8_t)offset * cie_info->code_align;
-        ALOGV("DW_CFA_advance_loc1: %d to 0x%x", (uint8_t)offset * cie_info->code_align, dstate->loc);
-        break;
-    case DW_CFA_advance_loc2:
-        if (!try_get_xbytes(memory, ptr, &offset, 2, cursor)) return false;
-        dstate->loc += (uint16_t)offset * cie_info->code_align;
-        ALOGV("DW_CFA_advance_loc2: %d to 0x%x", (uint16_t)offset * cie_info->code_align, dstate->loc);
-        break;
-    case DW_CFA_advance_loc4:
-        if (!try_get_xbytes(memory, ptr, &offset, 4, cursor)) return false;
-        dstate->loc += offset * cie_info->code_align;
-        ALOGV("DW_CFA_advance_loc4: %d to 0x%x", offset * cie_info->code_align, dstate->loc);
-        break;
-    case DW_CFA_offset_extended: // probably we don't have it on mips.
-        if (!try_get_uleb128(memory, ptr, &reg, cursor)) return false;
-        if (!try_get_uleb128(memory, ptr, &offset, cursor)) return false;
-        if (reg >= DWARF_REGISTERS) {
-            ALOGE("DW_CFA_offset_extended: r%d exceeds supported number of registers (%d)", reg, DWARF_REGISTERS);
-            return false;
-        }
-        dstate->regs[reg].rule = 'o';
-        dstate->regs[reg].value = offset * cie_info->data_align;
-        ALOGV("DW_CFA_offset_extended: r%d = o(%d)", reg, dstate->regs[reg].value);
-        break;
-    case DW_CFA_restore_extended: // probably we don't have it on mips.
-        if (!try_get_uleb128(memory, ptr, &reg, cursor)) return false;
-        if (reg >= DWARF_REGISTERS) {
-            ALOGE("DW_CFA_restore_extended: r%d exceeds supported number of registers (%d)", reg, DWARF_REGISTERS);
-            return false;
-        }
-        dstate->regs[reg].rule = stack->regs[reg].rule;
-        dstate->regs[reg].value = stack->regs[reg].value;
-        ALOGV("DW_CFA_restore: r%d = %c(%d)", reg, dstate->regs[reg].rule, dstate->regs[reg].value);
-        break;
-    case DW_CFA_undefined: // probably we don't have it on mips.
-        if (!try_get_uleb128(memory, ptr, &reg, cursor)) return false;
-        if (reg >= DWARF_REGISTERS) {
-            ALOGE("DW_CFA_undefined: r%d exceeds supported number of registers (%d)", reg, DWARF_REGISTERS);
-            return false;
-        }
-        dstate->regs[reg].rule = 'u';
-        dstate->regs[reg].value = 0;
-        ALOGV("DW_CFA_undefined: r%d", reg);
-        break;
-    case DW_CFA_same_value: // probably we don't have it on mips.
-        if (!try_get_uleb128(memory, ptr, &reg, cursor)) return false;
-        if (reg >= DWARF_REGISTERS) {
-            ALOGE("DW_CFA_undefined: r%d exceeds supported number of registers (%d)", reg, DWARF_REGISTERS);
-            return false;
-        }
-        dstate->regs[reg].rule = 's';
-        dstate->regs[reg].value = 0;
-        ALOGV("DW_CFA_same_value: r%d", reg);
-        break;
-    case DW_CFA_register: // probably we don't have it on mips.
-        if (!try_get_uleb128(memory, ptr, &reg, cursor)) return false;
-        /* that's new register actually, not offset */
-        if (!try_get_uleb128(memory, ptr, &offset, cursor)) return false;
-        if (reg >= DWARF_REGISTERS || offset >= DWARF_REGISTERS) {
-            ALOGE("DW_CFA_register: r%d or r%d exceeds supported number of registers (%d)", reg, offset, DWARF_REGISTERS);
-            return false;
-        }
-        dstate->regs[reg].rule = 'r';
-        dstate->regs[reg].value = offset;
-        ALOGV("DW_CFA_register: r%d = r(%d)", reg, dstate->regs[reg].value);
-        break;
-    case DW_CFA_remember_state:
-        if (*stack_ptr == DWARF_STATES_STACK) {
-            ALOGE("DW_CFA_remember_state: states stack overflow %d", *stack_ptr);
-            return false;
-        }
-        stack[(*stack_ptr)++] = *dstate;
-        ALOGV("DW_CFA_remember_state: stacktop moves to %d", *stack_ptr);
-        break;
-    case DW_CFA_restore_state:
-        /* We have CIE state saved at 0 position. It's not supposed to be taken
-           by DW_CFA_restore_state. */
-        if (*stack_ptr == 1) {
-            ALOGE("DW_CFA_restore_state: states stack is empty");
-            return false;
-        }
-        /* Don't touch location on restore. */
-        uintptr_t saveloc = dstate->loc;
-        *dstate = stack[--*stack_ptr];
-        dstate->loc = saveloc;
-        ALOGV("DW_CFA_restore_state: stacktop moves to %d", *stack_ptr);
-        break;
-    case DW_CFA_def_cfa:
-        if (!try_get_uleb128(memory, ptr, &reg, cursor)) return false;
-        if (!try_get_uleb128(memory, ptr, &offset, cursor)) return false;
-        dstate->cfa_reg = reg;
-        dstate->cfa_off = offset;
-        ALOGV("DW_CFA_def_cfa: %x(r%d)", offset, reg);
-        break;
-    case DW_CFA_def_cfa_register:
-        if (!try_get_uleb128(memory, ptr, &reg, cursor)) {
-            return false;
-        }
-        dstate->cfa_reg = reg;
-        ALOGV("DW_CFA_def_cfa_register: r%d", reg);
-        break;
-    case DW_CFA_def_cfa_offset:
-        if (!try_get_uleb128(memory, ptr, &offset, cursor)) {
-            return false;
-        }
-        dstate->cfa_off = offset;
-        ALOGV("DW_CFA_def_cfa_offset: %x", offset);
-        break;
-    default:
-        ALOGE("unrecognized DW_CFA_* instruction: 0x%x", inst);
-        return false;
-    }
-    return true;
-}
-
-/* Restoring particular register value based on dwarf state. */
-static bool get_old_register_value(const memory_t* memory, uint32_t cfa,
-                                   dwarf_state_t* dstate, uint8_t reg,
-                                   unwind_state_t* state, unwind_state_t* newstate) {
-    uint32_t addr;
-    switch (dstate->regs[reg].rule) {
-    case 0:
-        /* We don't have dstate updated for this register, so assuming value kept the same.
-           Normally we should look into state and return current value as the old one
-           but we don't have all registers in state to handle this properly */
-        ALOGV("get_old_register_value: value of r%d is the same", reg);
-        // for SP if it's not updated by dwarf rule we assume it's equal to CFA
-        // for PC if it's not updated by dwarf rule we assume it's equal to RA
-        if (reg == DWARF_SP) {
-            ALOGV("get_old_register_value: adjusting sp to CFA: 0x%x", cfa);
-            newstate->reg[reg] = cfa;
-        } else if (reg == DWARF_PC) {
-            ALOGV("get_old_register_value: adjusting PC to RA: 0x%x", newstate->reg[DWARF_RA]);
-            newstate->reg[reg] = newstate->reg[DWARF_RA];
-        } else {
-            newstate->reg[reg] = state->reg[reg];
-        }
-        break;
-    case 'o':
-        addr = cfa + (int32_t)dstate->regs[reg].value;
-        if (!try_get_word(memory, addr, &newstate->reg[reg])) {
-            ALOGE("get_old_register_value: can't read from 0x%x", addr);
-            return false;
-        }
-        ALOGV("get_old_register_value: r%d at 0x%x is 0x%x", reg, addr, newstate->reg[reg]);
-        break;
-    case 'r':
-        /* We don't have all registers in state so don't even try to look at 'r' */
-        ALOGE("get_old_register_value: register lookup not implemented yet");
-        break;
-    default:
-        ALOGE("get_old_register_value: unexpected rule:%c value:%d for register %d",
-              dstate->regs[reg].rule, (int32_t)dstate->regs[reg].value, reg);
-        return false;
-    }
-    return true;
-}
-
-/* Updaing state based on dwarf state. */
-static bool update_state(const memory_t* memory, unwind_state_t* state,
-                         dwarf_state_t* dstate) {
-    unwind_state_t newstate;
-    /* We can restore more registers here if we need them. Meanwile doing minimal work here. */
-    /* Getting CFA. */
-    uintptr_t cfa = 0;
-    if (dstate->cfa_reg == DWARF_SP) {
-        cfa = state->reg[DWARF_SP] + dstate->cfa_off;
-    } else if (dstate->cfa_reg == DWARF_FP) {
-        cfa = state->reg[DWARF_FP] + dstate->cfa_off;
-    } else {
-        ALOGE("update_state: unexpected CFA register: %d", dstate->cfa_reg);
-        return false;
-    }
-    ALOGV("update_state: new CFA: 0x%x", cfa);
-
-    /* Update registers. Order is important to allow RA to propagate to PC */
-    /* Getting FP. */
-    if (!get_old_register_value(memory, cfa, dstate, DWARF_FP, state, &newstate)) return false;
-    /* Getting SP. */
-    if (!get_old_register_value(memory, cfa, dstate, DWARF_SP, state, &newstate)) return false;
-    /* Getting RA. */
-    if (!get_old_register_value(memory, cfa, dstate, DWARF_RA, state, &newstate)) return false;
-    /* Getting PC. */
-    if (!get_old_register_value(memory, cfa, dstate, DWARF_PC, state, &newstate)) return false;
-
-    ALOGV("update_state: PC: 0x%x; restore PC: 0x%x", state->reg[DWARF_PC], newstate.reg[DWARF_PC]);
-    ALOGV("update_state: RA: 0x%x; restore RA: 0x%x", state->reg[DWARF_RA], newstate.reg[DWARF_RA]);
-    ALOGV("update_state: FP: 0x%x; restore FP: 0x%x", state->reg[DWARF_FP], newstate.reg[DWARF_FP]);
-    ALOGV("update_state: SP: 0x%x; restore SP: 0x%x", state->reg[DWARF_SP], newstate.reg[DWARF_SP]);
-
-    if (newstate.reg[DWARF_PC] == 0)
-        return false;
-
-    /* End backtrace if registers do not change */
-    if ((state->reg[DWARF_PC] == newstate.reg[DWARF_PC]) &&
-        (state->reg[DWARF_RA] == newstate.reg[DWARF_RA]) &&
-        (state->reg[DWARF_FP] == newstate.reg[DWARF_FP]) &&
-        (state->reg[DWARF_SP] == newstate.reg[DWARF_SP]))
-        return false;
-
-    *state = newstate;
-    return true;
-}
-
-/* Execute CIE and FDE instructions for FDE found with find_fde. */
-static bool execute_fde(const memory_t* memory,
-                        uintptr_t fde,
-                        unwind_state_t* state) {
-    uint32_t fde_length = 0;
-    uint32_t cie_length = 0;
-    uintptr_t cie = 0;
-    uintptr_t cie_offset = 0;
-    cie_info_t cie_i;
-    cie_info_t* cie_info = &cie_i;
-    fde_info_t fde_i;
-    fde_info_t* fde_info = &fde_i;
-    dwarf_state_t dwarf_state;
-    dwarf_state_t* dstate = &dwarf_state;
-    dwarf_state_t stack[DWARF_STATES_STACK];
-    uint8_t stack_ptr = 0;
-
-    memset(dstate, 0, sizeof(dwarf_state_t));
-    memset(cie_info, 0, sizeof(cie_info_t));
-    memset(fde_info, 0, sizeof(fde_info_t));
-
-    /* Read common CIE or FDE area:
-       1st word is length;
-       2nd word is ID: 0 for CIE, CIE pointer for FDE.
-    */
-    if (!try_get_word(memory, fde, &fde_length)) {
-        return false;
-    }
-    if ((int32_t)fde_length == -1) {
-        ALOGV("execute_fde: 64-bit dwarf detected, not implemented yet");
-        return false;
-    }
-    if (!try_get_word(memory, fde + 4, &cie_offset)) {
-        return false;
-    }
-    if (cie_offset == 0) {
-        /* This is CIE. We shouldn't be here normally. */
-        cie = fde;
-        cie_length = fde_length;
-    } else {
-        /* Find CIE. */
-        /* Positive cie_offset goes backward from current field. */
-        cie = fde + 4 - cie_offset;
-        if (!try_get_word(memory, cie, &cie_length)) {
-            return false;
-        }
-        if ((int32_t)cie_length == -1) {
-            ALOGV("execute_fde: 64-bit dwarf detected, not implemented yet");
-            return false;
-        }
-        if (!try_get_word(memory, cie + 4, &cie_offset)) {
-            return false;
-        }
-        if (cie_offset != 0) {
-            ALOGV("execute_fde: can't find CIE");
-            return false;
-        }
-    }
-    ALOGV("execute_fde: FDE length: %d", fde_length);
-    ALOGV("execute_fde: CIE pointer: %x", cie);
-    ALOGV("execute_fde: CIE length: %d", cie_length);
-
-    /* Read CIE:
-       Augmentation independent:
-       1st byte is version;
-       next x bytes is /0 terminated augmentation string;
-       next x bytes is unsigned LEB128 encoded code alignment factor;
-       next x bytes is signed LEB128 encoded data alignment factor;
-       next 1 (CIE version 1) or x (CIE version 3 unsigned LEB128) bytes is return register column;
-       Augmentation dependent:
-       if 'z' next x bytes is unsigned LEB128 encoded augmentation data size;
-       if 'L' next 1 byte is LSDA encoding;
-       if 'R' next 1 byte is FDE encoding;
-       if 'S' CIE represents signal handler stack frame;
-       if 'P' next 1 byte is personality encoding folowed by personality function pointer;
-       Next x bytes is CIE program.
-    */
-
-    uint32_t c = 8;
-    if (!try_get_byte(memory, cie, &cie_info->version, &c)) {
-        return false;
-    }
-    ALOGV("execute_fde: CIE version: %d", cie_info->version);
-    uint8_t ch;
-    do {
-        if (!try_get_byte(memory, cie, &ch, &c)) {
-            return false;
-        }
-        switch (ch) {
-        case '\0': break;
-        case 'z': cie_info->aug_z = 1; break;
-        case 'L': cie_info->aug_L = 1; break;
-        case 'R': cie_info->aug_R = 1; break;
-        case 'S': cie_info->aug_S = 1; break;
-        case 'P': cie_info->aug_P = 1; break;
-        default:
-            ALOGV("execute_fde: Unrecognized CIE augmentation char: '%c'", ch);
-            return false;
-            break;
-        }
-    } while (ch);
-    if (!try_get_uleb128(memory, cie, &cie_info->code_align, &c)) {
-        return false;
-    }
-    if (!try_get_sleb128(memory, cie, &cie_info->data_align, &c)) {
-        return false;
-    }
-    if (cie_info->version >= 3) {
-        if (!try_get_uleb128(memory, cie, &cie_info->reg, &c)) {
-            return false;
-        }
-    } else {
-        if (!try_get_byte(memory, cie, (uint8_t*)&cie_info->reg, &c)) {
-            return false;
-        }
-    }
-    ALOGV("execute_fde: CIE code alignment factor: %d", cie_info->code_align);
-    ALOGV("execute_fde: CIE data alignment factor: %d", cie_info->data_align);
-    if (cie_info->aug_z) {
-        if (!try_get_uleb128(memory, cie, &cie_info->aug_z, &c)) {
-            return false;
-        }
-    }
-    if (cie_info->aug_L) {
-        if (!try_get_byte(memory, cie, &cie_info->aug_L, &c)) {
-            return false;
-        }
-    } else {
-        /* Default encoding. */
-        cie_info->aug_L = DW_EH_PE_absptr;
-    }
-    if (cie_info->aug_R) {
-        if (!try_get_byte(memory, cie, &cie_info->aug_R, &c)) {
-            return false;
-        }
-    } else {
-        /* Default encoding. */
-        cie_info->aug_R = DW_EH_PE_absptr;
-    }
-    if (cie_info->aug_P) {
-        /* Get encoding of personality routine pointer. We don't use it now. */
-        if (!try_get_byte(memory, cie, (uint8_t*)&cie_info->aug_P, &c)) {
-            return false;
-        }
-        /* Get routine pointer. */
-        if (!read_dwarf(memory, cie, &cie_info->aug_P, (uint8_t)cie_info->aug_P, &c)) {
-            return false;
-        }
-    }
-    /* CIE program. */
-    /* Length field itself (4 bytes) is not included into length. */
-    stack[0] = *dstate;
-    stack_ptr = 1;
-    while (c < cie_length + 4) {
-        if (!execute_dwarf(memory, cie, cie_info, dstate, &c, stack, &stack_ptr)) {
-            return false;
-        }
-    }
-
-    /* We went directly to CIE. Normally it shouldn't occur. */
-    if (cie == fde) return true;
-
-    /* Go back to FDE. */
-    c = 8;
-    /* Read FDE:
-       Augmentation independent:
-       next x bytes (encoded as specified in CIE) is FDE starting address;
-       next x bytes (encoded as specified in CIE) is FDE number of instructions covered;
-       Augmentation dependent:
-       if 'z' next x bytes is unsigned LEB128 encoded augmentation data size;
-       if 'L' next x bytes is LSDA pointer (encoded as specified in CIE);
-       Next x bytes is FDE program.
-    */
-    if (!read_dwarf(memory, fde, &fde_info->start, (uint8_t)cie_info->aug_R, &c)) {
-        return false;
-    }
-    dstate->loc = fde_info->start;
-    ALOGV("execute_fde: FDE start: %x", dstate->loc);
-    if (!read_dwarf(memory, fde, &fde_info->length, 0, &c)) {
-        return false;
-    }
-    ALOGV("execute_fde: FDE length: %x", fde_info->length);
-    if (cie_info->aug_z) {
-        if (!try_get_uleb128(memory, fde, &fde_info->aug_z, &c)) {
-            return false;
-        }
-    }
-    if (cie_info->aug_L && cie_info->aug_L != DW_EH_PE_omit) {
-        if (!read_dwarf(memory, fde, &fde_info->aug_L, cie_info->aug_L, &c)) {
-            return false;
-        }
-    }
-    /* FDE program. */
-    /* Length field itself (4 bytes) is not included into length. */
-    /* Save CIE state as 0 element of stack. Used by DW_CFA_restore. */
-    stack[0] = *dstate;
-    stack_ptr = 1;
-    while (c < fde_length + 4 && state->reg[DWARF_PC] >= dstate->loc) {
-        if (!execute_dwarf(memory, fde, cie_info, dstate, &c, stack, &stack_ptr)) {
-            return false;
-        }
-        ALOGV("PC: %x, LOC: %x", state->reg[DWARF_PC], dstate->loc);
-    }
-
-    return update_state(memory, state, dstate);
-}
-
-static bool heuristic_state_update(const memory_t* memory, unwind_state_t* state)
-{
-    bool found_start = false;
-    int maxcheck = 1024;
-    int32_t stack_size = 0;
-    int32_t ra_offset = 0;
-    dwarf_state_t dwarf_state;
-    dwarf_state_t* dstate = &dwarf_state;
-
-    static struct {
-        uint32_t insn;
-        uint32_t mask;
-    } frame0sig[] = {
-        {0x3c1c0000, 0xffff0000}, /* lui     gp,xxxx */
-        {0x279c0000, 0xffff0000}, /* addiu   gp,gp,xxxx */
-        {0x039fe021, 0xffffffff}, /* addu    gp,gp,ra */
-    };
-    const int nframe0sig = sizeof(frame0sig)/sizeof(frame0sig[0]);
-    int f0 = nframe0sig;
-    memset(dstate, 0, sizeof(dwarf_state_t));
-
-    /* Search code backwards looking for function prologue */
-    for (uint32_t pc = state->reg[DWARF_PC]-4; maxcheck-- > 0 && !found_start; pc -= 4) {
-        uint32_t op;
-        int32_t immediate;
-
-        if (!try_get_word(memory, pc, &op))
-            return false;
-
-        // ALOGV("@0x%08x: 0x%08x\n", pc, op);
-
-        // Check for frame 0 signature
-        if ((op & frame0sig[f0].mask) == frame0sig[f0].insn) {
-            if (f0 == 0)
-                return false;
-            f0--;
-        }
-        else {
-            f0 = nframe0sig;
-        }
-
-        switch (op & 0xffff0000) {
-        case 0x27bd0000: // addiu sp, imm
-            // looking for stack being decremented
-            immediate = (((int32_t)op) << 16) >> 16;
-            if (immediate < 0) {
-                stack_size = -immediate;
-                ALOGV("@0x%08x: found stack adjustment=%d\n", pc, stack_size);
-            }
-            break;
-        case 0x039f0000: // e021
-
-        case 0xafbf0000: // sw ra, imm(sp)
-            ra_offset = (((int32_t)op) << 16) >> 16;
-            ALOGV("@0x%08x: found ra offset=%d\n", pc, ra_offset);
-            break;
-        case 0x3c1c0000: // lui gp
-            ALOGV("@0x%08x: found function boundary", pc);
-            found_start = true;
-            break;
-        default:
-            break;
-        }
-    }
-
-    dstate->cfa_reg = DWARF_SP;
-    dstate->cfa_off = stack_size;
-
-    if (ra_offset) {
-        dstate->regs[DWARF_RA].rule = 'o';
-        dstate->regs[DWARF_RA].value = -stack_size + ra_offset;
-    }
-
-    return update_state(memory, state, dstate);
-}
-
-static ssize_t unwind_backtrace_common(const memory_t* memory,
-        const map_info_t* map_info_list,
-        unwind_state_t* state, backtrace_frame_t* backtrace,
-        size_t ignore_depth, size_t max_depth) {
-
-    size_t ignored_frames = 0;
-    size_t returned_frames = 0;
-
-    ALOGV("Unwinding tid: %d", memory->tid);
-    ALOGV("PC: %x", state->reg[DWARF_PC]);
-    ALOGV("RA: %x", state->reg[DWARF_RA]);
-    ALOGV("FP: %x", state->reg[DWARF_FP]);
-    ALOGV("SP: %x", state->reg[DWARF_SP]);
-
-    for (size_t index = 0; returned_frames < max_depth; index++) {
-        uintptr_t fde = find_fde(memory, map_info_list, state->reg[DWARF_PC]);
-        backtrace_frame_t* frame = add_backtrace_entry(
-            index ? rewind_pc_arch(memory, state->reg[DWARF_PC]) : state->reg[DWARF_PC],
-            backtrace, ignore_depth, max_depth,
-            &ignored_frames, &returned_frames);
-        uint32_t stack_top = state->reg[DWARF_SP];
-
-        if (fde) {
-            /* Use FDE to update state */
-            if (!execute_fde(memory, fde, state))
-                break;
-        }
-        else {
-            /* FDE is not found, update state heuristically */
-            if (!heuristic_state_update(memory, state))
-                break;
-        }
-
-        if (frame) {
-            frame->stack_top = stack_top;
-            if (stack_top < state->reg[DWARF_SP]) {
-                frame->stack_size = state->reg[DWARF_SP] - stack_top;
-            }
-        }
-        ALOGV("Stack: 0x%x ... 0x%x - %d bytes", frame->stack_top, state->reg[DWARF_SP], frame->stack_size);
-    }
-    return returned_frames;
-}
-
-ssize_t unwind_backtrace_signal_arch(siginfo_t* siginfo __attribute__((unused)), void* sigcontext,
-        const map_info_t* map_info_list,
-        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) {
-    const ucontext_t* uc = (const ucontext_t*)sigcontext;
-
-    unwind_state_t state;
-    state.reg[DWARF_PC] = uc->uc_mcontext.pc;
-    state.reg[DWARF_RA] = uc->uc_mcontext.gregs[REG_RA];
-    state.reg[DWARF_FP] = uc->uc_mcontext.gregs[REG_S8];
-    state.reg[DWARF_SP] = uc->uc_mcontext.gregs[REG_SP];
-
-    ALOGV("unwind_backtrace_signal_arch: "
-          "ignore_depth=%d max_depth=%d pc=0x%08x sp=0x%08x ra=0x%08x\n",
-          ignore_depth, max_depth, state.reg[DWARF_PC], state.reg[DWARF_SP], state.reg[DWARF_RA]);
-
-    memory_t memory;
-    init_memory(&memory, map_info_list);
-    return unwind_backtrace_common(&memory, map_info_list,
-                                   &state, backtrace, ignore_depth, max_depth);
-}
-
-ssize_t unwind_backtrace_ptrace_arch(pid_t tid, const ptrace_context_t* context,
-        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) {
-
-    user_regs_struct regs;
-    if (ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
-        return -1;
-    }
-
-    unwind_state_t state;
-    state.reg[DWARF_PC] = regs.epc;
-    state.reg[DWARF_RA] = regs.regs[REG_RA];
-    state.reg[DWARF_FP] = regs.regs[REG_S8];
-    state.reg[DWARF_SP] = regs.regs[REG_SP];
-
-    ALOGV("unwind_backtrace_ptrace_arch: "
-          "ignore_depth=%d max_depth=%d pc=0x%08x sp=0x%08x ra=0x%08x\n",
-          ignore_depth, max_depth, state.reg[DWARF_PC], state.reg[DWARF_SP], state.reg[DWARF_RA]);
-
-    memory_t memory;
-    init_memory_ptrace(&memory, tid);
-    return unwind_backtrace_common(&memory, context->map_info_list,
-                                   &state, backtrace, ignore_depth, max_depth);
-}
diff --git a/libcorkscrew/arch-mips/dwarf.h b/libcorkscrew/arch-mips/dwarf.h
deleted file mode 100644
index 8504ea0..0000000
--- a/libcorkscrew/arch-mips/dwarf.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-/*
- * Dwarf2 data encoding flags.
- */
-
-#define DW_EH_PE_absptr         0x00
-#define DW_EH_PE_omit           0xff
-#define DW_EH_PE_uleb128        0x01
-#define DW_EH_PE_udata2         0x02
-#define DW_EH_PE_udata4         0x03
-#define DW_EH_PE_udata8         0x04
-#define DW_EH_PE_sleb128        0x09
-#define DW_EH_PE_sdata2         0x0A
-#define DW_EH_PE_sdata4         0x0B
-#define DW_EH_PE_sdata8         0x0C
-#define DW_EH_PE_signed         0x08
-#define DW_EH_PE_pcrel          0x10
-#define DW_EH_PE_textrel        0x20
-#define DW_EH_PE_datarel        0x30
-#define DW_EH_PE_funcrel        0x40
-#define DW_EH_PE_aligned        0x50
-#define DW_EH_PE_indirect       0x80
-
-/*
- * Dwarf2 call frame instructions.
- */
-
-typedef enum {
-    DW_CFA_advance_loc = 0x40,
-    DW_CFA_offset = 0x80,
-    DW_CFA_restore = 0xc0,
-    DW_CFA_nop = 0x00,
-    DW_CFA_set_loc = 0x01,
-    DW_CFA_advance_loc1 = 0x02,
-    DW_CFA_advance_loc2 = 0x03,
-    DW_CFA_advance_loc4 = 0x04,
-    DW_CFA_offset_extended = 0x05,
-    DW_CFA_restore_extended = 0x06,
-    DW_CFA_undefined = 0x07,
-    DW_CFA_same_value = 0x08,
-    DW_CFA_register = 0x09,
-    DW_CFA_remember_state = 0x0a,
-    DW_CFA_restore_state = 0x0b,
-    DW_CFA_def_cfa = 0x0c,
-    DW_CFA_def_cfa_register = 0x0d,
-    DW_CFA_def_cfa_offset = 0x0e
-} dwarf_CFA;
-
-/*
- * eh_frame_hdr information.
-*/
-
-typedef struct {
-      uint8_t version;
-      uint8_t eh_frame_ptr_enc;
-      uint8_t fde_count_enc;
-      uint8_t fde_table_enc;
-      uintptr_t eh_frame_ptr;
-      uint32_t fde_count;
-} eh_frame_hdr_info_t;
-
-/*
- * CIE information.
-*/
-
-typedef struct {
-      uint8_t version;
-      uint32_t code_align;
-      uint32_t data_align;
-      uint32_t reg;
-      uint32_t aug_z;
-      uint8_t aug_L;
-      uint8_t aug_R;
-      uint8_t aug_S;
-      uint32_t aug_P;
-} cie_info_t;
-
-/*
- * FDE information.
-*/
-
-typedef struct {
-      uint32_t start;
-      uint32_t length; // number of instructions covered by FDE
-      uint32_t aug_z;
-      uint32_t aug_L;
-} fde_info_t;
-
-/*
- * Dwarf state.
-*/
-
-/* Stack of states: required for DW_CFA_remember_state/DW_CFA_restore_state
-   30 should be enough */
-#define DWARF_STATES_STACK 30
-
-typedef struct {
-    char rule;         // rule: o - offset(value); r - register(value)
-    uint32_t value;    // value
-} reg_rule_t;
-
-/* Dwarf preserved number of registers for mips */
-typedef enum
-  {
-    UNW_MIPS_R0,
-    UNW_MIPS_R1,
-    UNW_MIPS_R2,
-    UNW_MIPS_R3,
-    UNW_MIPS_R4,
-    UNW_MIPS_R5,
-    UNW_MIPS_R6,
-    UNW_MIPS_R7,
-    UNW_MIPS_R8,
-    UNW_MIPS_R9,
-    UNW_MIPS_R10,
-    UNW_MIPS_R11,
-    UNW_MIPS_R12,
-    UNW_MIPS_R13,
-    UNW_MIPS_R14,
-    UNW_MIPS_R15,
-    UNW_MIPS_R16,
-    UNW_MIPS_R17,
-    UNW_MIPS_R18,
-    UNW_MIPS_R19,
-    UNW_MIPS_R20,
-    UNW_MIPS_R21,
-    UNW_MIPS_R22,
-    UNW_MIPS_R23,
-    UNW_MIPS_R24,
-    UNW_MIPS_R25,
-    UNW_MIPS_R26,
-    UNW_MIPS_R27,
-    UNW_MIPS_R28,
-    UNW_MIPS_R29,
-    UNW_MIPS_R30,
-    UNW_MIPS_R31,
-
-    UNW_MIPS_PC = 34,
-
-    /* FIXME: Other registers!  */
-
-    /* For MIPS, the CFA is the value of SP (r29) at the call site in the
-       previous frame.  */
-    UNW_MIPS_CFA,
-
-    UNW_TDEP_LASTREG,
-
-    UNW_TDEP_LAST_REG = UNW_MIPS_R31,
-
-    UNW_TDEP_IP = UNW_MIPS_R31,
-    UNW_TDEP_SP = UNW_MIPS_R29,
-    UNW_TDEP_EH = UNW_MIPS_R0   /* FIXME.  */
-
-  }
-mips_regnum_t;
-
-#define DWARF_REGISTERS UNW_TDEP_LASTREG
-
-typedef struct {
-    uintptr_t loc;     // location (ip)
-    uint8_t cfa_reg;   // index of register where CFA location stored
-    intptr_t cfa_off;  // offset
-    reg_rule_t regs[DWARF_REGISTERS]; // dwarf preserved registers for mips
-} dwarf_state_t;
-
-/* DWARF registers we are caring about. */
-
-
-#define DWARF_SP      UNW_MIPS_R29
-#define DWARF_RA      UNW_MIPS_R31
-#define DWARF_PC      UNW_MIPS_PC
-#define DWARF_FP      UNW_MIPS_CFA /* FIXME is this correct? */
diff --git a/libcorkscrew/arch-mips/ptrace-mips.c b/libcorkscrew/arch-mips/ptrace-mips.c
deleted file mode 100644
index ba3b60a..0000000
--- a/libcorkscrew/arch-mips/ptrace-mips.c
+++ /dev/null
@@ -1,77 +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.
- */
-
-#define LOG_TAG "Corkscrew"
-//#define LOG_NDEBUG 0
-
-#include "../ptrace-arch.h"
-
-#include <stddef.h>
-#include <elf.h>
-#include <cutils/log.h>
-
-static void load_eh_frame_hdr(pid_t pid, map_info_t* mi, uintptr_t *eh_frame_hdr) {
-    uint32_t elf_phoff;
-    uint32_t elf_phentsize_ehsize;
-    uint32_t elf_shentsize_phnum;
-
-
-    try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_phoff), &elf_phoff);
-    ALOGV("reading 0x%08x elf_phoff:%x",  mi->start + offsetof(Elf32_Ehdr, e_phoff), elf_phoff);
-    try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_ehsize), &elf_phentsize_ehsize);
-    ALOGV("reading 0x%08x elf_phentsize_ehsize:%x", mi->start + offsetof(Elf32_Ehdr, e_ehsize), elf_phentsize_ehsize);
-    try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_phnum), &elf_shentsize_phnum);
-    ALOGV("reading 0x%08x elf_shentsize_phnum:%x", mi->start + offsetof(Elf32_Ehdr, e_phnum), elf_shentsize_phnum);
-
-
-
-    if (try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_phoff), &elf_phoff)
-            && try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_ehsize),
-                    &elf_phentsize_ehsize)
-            && try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_phnum),
-                    &elf_shentsize_phnum)) {
-        uint32_t elf_phentsize = elf_phentsize_ehsize >> 16;
-        uint32_t elf_phnum = elf_shentsize_phnum & 0xffff;
-        for (uint32_t i = 0; i < elf_phnum; i++) {
-            uintptr_t elf_phdr = mi->start + elf_phoff + i * elf_phentsize;
-            uint32_t elf_phdr_type;
-            if (!try_get_word_ptrace(pid, elf_phdr + offsetof(Elf32_Phdr, p_type), &elf_phdr_type)) {
-                break;
-            }
-            if (elf_phdr_type == PT_GNU_EH_FRAME) {
-                uint32_t elf_phdr_offset;
-                if (!try_get_word_ptrace(pid, elf_phdr + offsetof(Elf32_Phdr, p_offset),
-                        &elf_phdr_offset)) {
-                    break;
-                }
-                *eh_frame_hdr = mi->start + elf_phdr_offset;
-                ALOGV("Parsed .eh_frame_hdr info for %s: start=0x%08x", mi->name, *eh_frame_hdr);
-                return;
-            }
-        }
-    }
-    *eh_frame_hdr = 0;
-}
-
-void load_ptrace_map_info_data_arch(pid_t pid, map_info_t* mi, map_info_data_t* data) {
-    ALOGV("load_ptrace_map_info_data_arch");
-    load_eh_frame_hdr(pid, mi, &data->eh_frame_hdr);
-}
-
-void free_ptrace_map_info_data_arch(map_info_t* mi __attribute__((unused)),
-                                    map_info_data_t* data __attribute__((unused))) {
-    ALOGV("free_ptrace_map_info_data_arch");
-}
diff --git a/libcorkscrew/arch-x86/backtrace-x86.c b/libcorkscrew/arch-x86/backtrace-x86.c
deleted file mode 100755
index df486de..0000000
--- a/libcorkscrew/arch-x86/backtrace-x86.c
+++ /dev/null
@@ -1,823 +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.
- */
-
-/*
- * Backtracing functions for x86.
- */
-
-#define LOG_TAG "Corkscrew"
-//#define LOG_NDEBUG 0
-
-#include "../backtrace-arch.h"
-#include "../backtrace-helper.h"
-#include "../ptrace-arch.h"
-#include <corkscrew/ptrace.h>
-#include "dwarf.h"
-
-#include <stdlib.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <limits.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/ptrace.h>
-#include <cutils/log.h>
-
-#if defined(__APPLE__)
-
-#define _XOPEN_SOURCE
-#include <ucontext.h>
-
-#else
-
-// glibc has its own renaming of the Linux kernel's structures.
-#define __USE_GNU // For REG_EBP, REG_ESP, and REG_EIP.
-#include <ucontext.h>
-
-#endif
-
-/* Unwind state. */
-typedef struct {
-    uint32_t reg[DWARF_REGISTERS];
-} unwind_state_t;
-
-typedef struct {
-    backtrace_frame_t* backtrace;
-    size_t ignore_depth;
-    size_t max_depth;
-    size_t ignored_frames;
-    size_t returned_frames;
-    memory_t memory;
-} backtrace_state_t;
-
-uintptr_t rewind_pc_arch(const memory_t* memory __attribute__((unused)), uintptr_t pc) {
-    /* TODO: x86 instructions are 1-16 bytes, to define exact size of previous instruction
-       we have to disassemble from the function entry point up to pc.
-       Returning pc-1 is probably enough for now, the only drawback is that
-       it points somewhere between the first byte of instruction we are looking for and
-       the first byte of the next instruction. */
-
-    return pc-1;
-    /* TODO: We should adjust that for the signal frames and return pc for them instead of pc-1.
-       To recognize signal frames we should read cie_info property. */
-}
-
-/* Read byte through 4 byte cache. Usually we read byte by byte and updating cursor. */
-static bool try_get_byte(const memory_t* memory, uintptr_t ptr, uint8_t* out_value, uint32_t* cursor) {
-    static uintptr_t lastptr;
-    static uint32_t buf;
-
-    ptr += *cursor;
-
-    if (ptr < lastptr || lastptr + 3 < ptr) {
-        lastptr = (ptr >> 2) << 2;
-        if (!try_get_word(memory, lastptr, &buf)) {
-            return false;
-        }
-    }
-    *out_value = (uint8_t)((buf >> ((ptr & 3) * 8)) & 0xff);
-    ++*cursor;
-    return true;
-}
-
-/* Getting X bytes. 4 is maximum for now. */
-static bool try_get_xbytes(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint8_t bytes, uint32_t* cursor) {
-    uint32_t data = 0;
-    if (bytes > 4) {
-        ALOGE("can't read more than 4 bytes, trying to read %d", bytes);
-        return false;
-    }
-    for (int i = 0; i < bytes; i++) {
-        uint8_t buf;
-        if (!try_get_byte(memory, ptr, &buf, cursor)) {
-            return false;
-        }
-        data |= (uint32_t)buf << (i * 8);
-    }
-    *out_value = data;
-    return true;
-}
-
-/* Reads signed/unsigned LEB128 encoded data. From 1 to 4 bytes. */
-static bool try_get_leb128(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint32_t* cursor, bool sign_extend) {
-    uint8_t buf = 0;
-    uint32_t val = 0;
-    uint8_t c = 0;
-    do {
-       if (!try_get_byte(memory, ptr, &buf, cursor)) {
-           return false;
-       }
-       val |= ((uint32_t)buf & 0x7f) << (c * 7);
-       c++;
-    } while (buf & 0x80 && (c * 7) <= 32);
-    if (c * 7 > 32) {
-       ALOGE("%s: data exceeds expected 4 bytes maximum", __FUNCTION__);
-       return false;
-    }
-    if (sign_extend) {
-        if (buf & 0x40) {
-            val |= ((uint32_t)-1 << (c * 7));
-        }
-    }
-    *out_value = val;
-    return true;
-}
-
-/* Reads signed LEB128 encoded data. From 1 to 4 bytes. */
-static bool try_get_sleb128(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint32_t* cursor) {
-  return try_get_leb128(memory, ptr, out_value, cursor, true);
-}
-
-/* Reads unsigned LEB128 encoded data. From 1 to 4 bytes. */
-static bool try_get_uleb128(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint32_t* cursor) {
-  return try_get_leb128(memory, ptr, out_value, cursor, false);
-}
-
-/* Getting data encoded by dwarf encodings. */
-static bool read_dwarf(const memory_t* memory, uintptr_t ptr, uint32_t* out_value, uint8_t encoding, uint32_t* cursor) {
-    uint32_t data = 0;
-    bool issigned = true;
-    uintptr_t addr = ptr + *cursor;
-    /* Lower 4 bits is data type/size */
-    /* TODO: add more encodings if it becomes necessary */
-    switch (encoding & 0xf) {
-        case DW_EH_PE_absptr:
-            if (!try_get_xbytes(memory, ptr, &data, 4, cursor)) {
-                return false;
-            }
-            *out_value = data;
-            return true;
-        case DW_EH_PE_udata4:
-            issigned = false;
-        case DW_EH_PE_sdata4:
-            if (!try_get_xbytes(memory, ptr, &data, 4, cursor)) {
-                return false;
-            }
-            break;
-        default:
-            ALOGE("unrecognized dwarf lower part encoding: 0x%x", encoding);
-            return false;
-    }
-    /* Higher 4 bits is modifier */
-    /* TODO: add more encodings if it becomes necessary */
-    switch (encoding & 0xf0) {
-        case 0:
-            *out_value = data;
-            break;
-        case DW_EH_PE_pcrel:
-            if (issigned) {
-                *out_value = addr + (int32_t)data;
-            } else {
-                *out_value = addr + data;
-            }
-            break;
-        /* Assuming ptr is correct base to calculate datarel */
-        case DW_EH_PE_datarel:
-            if (issigned) {
-                *out_value = ptr + (int32_t)data;
-            } else {
-                *out_value = ptr + data;
-            }
-            break;
-        default:
-            ALOGE("unrecognized dwarf higher part encoding: 0x%x", encoding);
-            return false;
-    }
-    return true;
-}
-
-/* Having PC find corresponding FDE by reading .eh_frame_hdr section data. */
-static uintptr_t find_fde(const memory_t* memory,
-                          const map_info_t* map_info_list, uintptr_t pc) {
-    if (!pc) {
-        ALOGV("find_fde: pc is zero, no eh_frame");
-        return 0;
-    }
-    const map_info_t* mi = find_map_info(map_info_list, pc);
-    if (!mi) {
-        ALOGV("find_fde: no map info for pc:0x%x", pc);
-        return 0;
-    }
-    const map_info_data_t* midata = mi->data;
-    if (!midata) {
-        ALOGV("find_fde: no eh_frame_hdr for map: start=0x%x, end=0x%x", mi->start, mi->end);
-        return 0;
-    }
-
-    eh_frame_hdr_info_t eh_hdr_info;
-    memset(&eh_hdr_info, 0, sizeof(eh_frame_hdr_info_t));
-
-    /* Getting the first word of eh_frame_hdr:
-        1st byte is version;
-        2nd byte is encoding of pointer to eh_frames;
-        3rd byte is encoding of count of FDEs in lookup table;
-        4th byte is encoding of lookup table entries.
-    */
-    uintptr_t eh_frame_hdr = midata->eh_frame_hdr;
-    uint32_t c = 0;
-    if (!try_get_byte(memory, eh_frame_hdr, &eh_hdr_info.version, &c)) return 0;
-    if (!try_get_byte(memory, eh_frame_hdr, &eh_hdr_info.eh_frame_ptr_enc, &c)) return 0;
-    if (!try_get_byte(memory, eh_frame_hdr, &eh_hdr_info.fde_count_enc, &c)) return 0;
-    if (!try_get_byte(memory, eh_frame_hdr, &eh_hdr_info.fde_table_enc, &c)) return 0;
-
-    /* TODO: 3rd byte can be DW_EH_PE_omit, that means no lookup table available and we should
-       try to parse eh_frame instead. Not sure how often it may occur, skipping now.
-    */
-    if (eh_hdr_info.version != 1) {
-        ALOGV("find_fde: eh_frame_hdr version %d is not supported", eh_hdr_info.version);
-        return 0;
-    }
-    /* Getting the data:
-        2nd word is eh_frame pointer (normally not used, because lookup table has all we need);
-        3rd word is count of FDEs in the lookup table;
-        starting from 4 word there is FDE lookup table (pairs of PC and FDE pointer) sorted by PC;
-    */
-    if (!read_dwarf(memory, eh_frame_hdr, &eh_hdr_info.eh_frame_ptr, eh_hdr_info.eh_frame_ptr_enc, &c)) return 0;
-    if (!read_dwarf(memory, eh_frame_hdr, &eh_hdr_info.fde_count, eh_hdr_info.fde_count_enc, &c)) return 0;
-    ALOGV("find_fde: found %d FDEs", eh_hdr_info.fde_count);
-
-    int32_t low = 0;
-    int32_t high = eh_hdr_info.fde_count;
-    uintptr_t start = 0;
-    uintptr_t fde = 0;
-    /* eh_frame_hdr + c points to lookup table at this point. */
-    while (low <= high) {
-        uint32_t mid = (high + low)/2;
-        uint32_t entry = c + mid * 8;
-        if (!read_dwarf(memory, eh_frame_hdr, &start, eh_hdr_info.fde_table_enc, &entry)) return 0;
-        if (pc <= start) {
-            high = mid - 1;
-        } else {
-            low = mid + 1;
-        }
-    }
-    /* Value found is at high. */
-    if (high < 0) {
-        ALOGV("find_fde: pc %x is out of FDE bounds: %x", pc, start);
-        return 0;
-    }
-    c += high * 8;
-    if (!read_dwarf(memory, eh_frame_hdr, &start, eh_hdr_info.fde_table_enc, &c)) return 0;
-    if (!read_dwarf(memory, eh_frame_hdr, &fde, eh_hdr_info.fde_table_enc, &c)) return 0;
-    ALOGV("pc 0x%x, ENTRY %d: start=0x%x, fde=0x%x", pc, high, start, fde);
-    return fde;
-}
-
-/* Execute single dwarf instruction and update dwarf state accordingly. */
-static bool execute_dwarf(const memory_t* memory, uintptr_t ptr, cie_info_t* cie_info,
-                          dwarf_state_t* dstate, uint32_t* cursor,
-                          dwarf_state_t* stack, uint8_t* stack_ptr) {
-    uint8_t inst;
-    uint8_t op = 0;
-
-    if (!try_get_byte(memory, ptr, &inst, cursor)) {
-        return false;
-    }
-    ALOGV("DW_CFA inst: 0x%x", inst);
-
-    /* For some instructions upper 2 bits is opcode and lower 6 bits is operand. See dwarf-2.0 7.23. */
-    if (inst & 0xc0) {
-        op = inst & 0x3f;
-        inst &= 0xc0;
-    }
-
-    switch ((dwarf_CFA)inst) {
-        uint32_t reg = 0;
-        uint32_t offset = 0;
-        case DW_CFA_advance_loc:
-            dstate->loc += op * cie_info->code_align;
-            ALOGV("DW_CFA_advance_loc: %d to 0x%x", op, dstate->loc);
-            break;
-        case DW_CFA_offset:
-            if (!try_get_uleb128(memory, ptr, &offset, cursor)) return false;
-            dstate->regs[op].rule = 'o';
-            dstate->regs[op].value = offset * cie_info->data_align;
-            ALOGV("DW_CFA_offset: r%d = o(%d)", op, dstate->regs[op].value);
-            break;
-        case DW_CFA_restore:
-            dstate->regs[op].rule = stack->regs[op].rule;
-            dstate->regs[op].value = stack->regs[op].value;
-            ALOGV("DW_CFA_restore: r%d = %c(%d)", op, dstate->regs[op].rule, dstate->regs[op].value);
-            break;
-        case DW_CFA_nop:
-            break;
-        case DW_CFA_set_loc: // probably we don't have it on x86.
-            if (!try_get_xbytes(memory, ptr, &offset, 4, cursor)) return false;
-            if (offset < dstate->loc) {
-                ALOGE("DW_CFA_set_loc: attempt to move location backward");
-                return false;
-            }
-            dstate->loc = offset * cie_info->code_align;
-            ALOGV("DW_CFA_set_loc: %d to 0x%x", offset * cie_info->code_align, dstate->loc);
-            break;
-        case DW_CFA_advance_loc1:
-            if (!try_get_byte(memory, ptr, (uint8_t*)&offset, cursor)) return false;
-            dstate->loc += (uint8_t)offset * cie_info->code_align;
-            ALOGV("DW_CFA_advance_loc1: %d to 0x%x", (uint8_t)offset * cie_info->code_align, dstate->loc);
-            break;
-        case DW_CFA_advance_loc2:
-            if (!try_get_xbytes(memory, ptr, &offset, 2, cursor)) return false;
-            dstate->loc += (uint16_t)offset * cie_info->code_align;
-            ALOGV("DW_CFA_advance_loc2: %d to 0x%x", (uint16_t)offset * cie_info->code_align, dstate->loc);
-            break;
-        case DW_CFA_advance_loc4:
-            if (!try_get_xbytes(memory, ptr, &offset, 4, cursor)) return false;
-            dstate->loc += offset * cie_info->code_align;
-            ALOGV("DW_CFA_advance_loc4: %d to 0x%x", offset * cie_info->code_align, dstate->loc);
-            break;
-        case DW_CFA_offset_extended: // probably we don't have it on x86.
-            if (!try_get_uleb128(memory, ptr, &reg, cursor)) return false;
-            if (!try_get_uleb128(memory, ptr, &offset, cursor)) return false;
-            if (reg >= DWARF_REGISTERS) {
-                ALOGE("DW_CFA_offset_extended: r%d exceeds supported number of registers (%d)", reg, DWARF_REGISTERS);
-                return false;
-            }
-            dstate->regs[reg].rule = 'o';
-            dstate->regs[reg].value = offset * cie_info->data_align;
-            ALOGV("DW_CFA_offset_extended: r%d = o(%d)", reg, dstate->regs[reg].value);
-            break;
-        case DW_CFA_restore_extended: // probably we don't have it on x86.
-            if (!try_get_uleb128(memory, ptr, &reg, cursor)) return false;
-            if (reg >= DWARF_REGISTERS) {
-                ALOGE("DW_CFA_restore_extended: r%d exceeds supported number of registers (%d)", reg, DWARF_REGISTERS);
-                return false;
-            }
-            dstate->regs[reg].rule = stack->regs[reg].rule;
-            dstate->regs[reg].value = stack->regs[reg].value;
-            ALOGV("DW_CFA_restore: r%d = %c(%d)", reg, dstate->regs[reg].rule, dstate->regs[reg].value);
-            break;
-        case DW_CFA_undefined: // probably we don't have it on x86.
-            if (!try_get_uleb128(memory, ptr, &reg, cursor)) return false;
-            if (reg >= DWARF_REGISTERS) {
-                ALOGE("DW_CFA_undefined: r%d exceeds supported number of registers (%d)", reg, DWARF_REGISTERS);
-                return false;
-            }
-            dstate->regs[reg].rule = 'u';
-            dstate->regs[reg].value = 0;
-            ALOGV("DW_CFA_undefined: r%d", reg);
-            break;
-        case DW_CFA_same_value: // probably we don't have it on x86.
-            if (!try_get_uleb128(memory, ptr, &reg, cursor)) return false;
-            if (reg >= DWARF_REGISTERS) {
-                ALOGE("DW_CFA_undefined: r%d exceeds supported number of registers (%d)", reg, DWARF_REGISTERS);
-                return false;
-            }
-            dstate->regs[reg].rule = 's';
-            dstate->regs[reg].value = 0;
-            ALOGV("DW_CFA_same_value: r%d", reg);
-            break;
-        case DW_CFA_register: // probably we don't have it on x86.
-            if (!try_get_uleb128(memory, ptr, &reg, cursor)) return false;
-            /* that's new register actually, not offset */
-            if (!try_get_uleb128(memory, ptr, &offset, cursor)) return false;
-            if (reg >= DWARF_REGISTERS || offset >= DWARF_REGISTERS) {
-                ALOGE("DW_CFA_register: r%d or r%d exceeds supported number of registers (%d)", reg, offset, DWARF_REGISTERS);
-                return false;
-            }
-            dstate->regs[reg].rule = 'r';
-            dstate->regs[reg].value = offset;
-            ALOGV("DW_CFA_register: r%d = r(%d)", reg, dstate->regs[reg].value);
-            break;
-        case DW_CFA_remember_state:
-            if (*stack_ptr == DWARF_STATES_STACK) {
-                ALOGE("DW_CFA_remember_state: states stack overflow %d", *stack_ptr);
-                return false;
-            }
-            stack[(*stack_ptr)++] = *dstate;
-            ALOGV("DW_CFA_remember_state: stacktop moves to %d", *stack_ptr);
-            break;
-        case DW_CFA_restore_state:
-            /* We have CIE state saved at 0 position. It's not supposed to be taken
-               by DW_CFA_restore_state. */
-            if (*stack_ptr == 1) {
-                ALOGE("DW_CFA_restore_state: states stack is empty");
-                return false;
-            }
-            /* Don't touch location on restore. */
-            uintptr_t saveloc = dstate->loc;
-            *dstate = stack[--*stack_ptr];
-            dstate->loc = saveloc;
-            ALOGV("DW_CFA_restore_state: stacktop moves to %d", *stack_ptr);
-            break;
-        case DW_CFA_def_cfa:
-            if (!try_get_uleb128(memory, ptr, &reg, cursor)) return false;
-            if (!try_get_uleb128(memory, ptr, &offset, cursor)) return false;
-            dstate->cfa_reg = reg;
-            dstate->cfa_off = offset;
-            ALOGV("DW_CFA_def_cfa: %x(r%d)", offset, reg);
-            break;
-        case DW_CFA_def_cfa_register:
-            if (!try_get_uleb128(memory, ptr, &reg, cursor)) {
-                return false;
-            }
-            dstate->cfa_reg = reg;
-            ALOGV("DW_CFA_def_cfa_register: r%d", reg);
-            break;
-        case DW_CFA_def_cfa_offset:
-            if (!try_get_uleb128(memory, ptr, &offset, cursor)) {
-                return false;
-            }
-            dstate->cfa_off = offset;
-            ALOGV("DW_CFA_def_cfa_offset: %x", offset);
-            break;
-        default:
-            ALOGE("unrecognized DW_CFA_* instruction: 0x%x", inst);
-            return false;
-    }
-    return true;
-}
-
-/* Restoring particular register value based on dwarf state. */
-static bool get_old_register_value(const memory_t* memory, uint32_t cfa,
-                                   dwarf_state_t* dstate, uint8_t reg,
-                                   unwind_state_t* state, unwind_state_t* newstate) {
-    uint32_t addr;
-    switch (dstate->regs[reg].rule) {
-        case 0:
-            /* We don't have dstate updated for this register, so assuming value kept the same.
-               Normally we should look into state and return current value as the old one
-               but we don't have all registers in state to handle this properly */
-            ALOGV("get_old_register_value: value of r%d is the same", reg);
-            // for ESP if it's not updated by dwarf rule we assume it's equal to CFA
-            if (reg == DWARF_ESP) {
-                ALOGV("get_old_register_value: adjusting esp to CFA: 0x%x", cfa);
-                newstate->reg[reg] = cfa;
-            } else {
-                newstate->reg[reg] = state->reg[reg];
-            }
-            break;
-        case 'o':
-            addr = cfa + (int32_t)dstate->regs[reg].value;
-            if (!try_get_word(memory, addr, &newstate->reg[reg])) {
-                ALOGE("get_old_register_value: can't read from 0x%x", addr);
-                return false;
-            }
-            ALOGV("get_old_register_value: r%d at 0x%x is 0x%x", reg, addr, newstate->reg[reg]);
-            break;
-        case 'r':
-            /* We don't have all registers in state so don't even try to look at 'r' */
-            ALOGE("get_old_register_value: register lookup not implemented yet");
-            break;
-        default:
-            ALOGE("get_old_register_value: unexpected rule:%c value:%d for register %d",
-                   dstate->regs[reg].rule, (int32_t)dstate->regs[reg].value, reg);
-            return false;
-    }
-    return true;
-}
-
-/* Updaing state based on dwarf state. */
-static bool update_state(const memory_t* memory, unwind_state_t* state,
-                         dwarf_state_t* dstate) {
-    unwind_state_t newstate;
-    /* We can restore more registers here if we need them. Meanwile doing minimal work here. */
-    /* Getting CFA. */
-    uintptr_t cfa = 0;
-    if (dstate->cfa_reg == DWARF_ESP) {
-        cfa = state->reg[DWARF_ESP] + dstate->cfa_off;
-    } else if (dstate->cfa_reg == DWARF_EBP) {
-        cfa = state->reg[DWARF_EBP] + dstate->cfa_off;
-    } else {
-        ALOGE("update_state: unexpected CFA register: %d", dstate->cfa_reg);
-        return false;
-    }
-    ALOGV("update_state: new CFA: 0x%x", cfa);
-    /* Getting EIP. */
-    if (!get_old_register_value(memory, cfa, dstate, DWARF_EIP, state, &newstate)) return false;
-    /* Getting EBP. */
-    if (!get_old_register_value(memory, cfa, dstate, DWARF_EBP, state, &newstate)) return false;
-    /* Getting ESP. */
-    if (!get_old_register_value(memory, cfa, dstate, DWARF_ESP, state, &newstate)) return false;
-
-    ALOGV("update_state: IP:  0x%x; restore IP:  0x%x", state->reg[DWARF_EIP], newstate.reg[DWARF_EIP]);
-    ALOGV("update_state: EBP: 0x%x; restore EBP: 0x%x", state->reg[DWARF_EBP], newstate.reg[DWARF_EBP]);
-    ALOGV("update_state: ESP: 0x%x; restore ESP: 0x%x", state->reg[DWARF_ESP], newstate.reg[DWARF_ESP]);
-    *state = newstate;
-    return true;
-}
-
-/* Execute CIE and FDE instructions for FDE found with find_fde. */
-static bool execute_fde(const memory_t* memory,
-                        uintptr_t fde,
-                        unwind_state_t* state) {
-    uint32_t fde_length = 0;
-    uint32_t cie_length = 0;
-    uintptr_t cie = 0;
-    uintptr_t cie_offset = 0;
-    cie_info_t cie_i;
-    cie_info_t* cie_info = &cie_i;
-    fde_info_t fde_i;
-    fde_info_t* fde_info = &fde_i;
-    dwarf_state_t dwarf_state;
-    dwarf_state_t* dstate = &dwarf_state;
-    dwarf_state_t stack[DWARF_STATES_STACK];
-    uint8_t stack_ptr = 0;
-
-    memset(dstate, 0, sizeof(dwarf_state_t));
-    memset(cie_info, 0, sizeof(cie_info_t));
-    memset(fde_info, 0, sizeof(fde_info_t));
-
-    /* Read common CIE or FDE area:
-        1st word is length;
-        2nd word is ID: 0 for CIE, CIE pointer for FDE.
-    */
-    if (!try_get_word(memory, fde, &fde_length)) {
-        return false;
-    }
-    if ((int32_t)fde_length == -1) {
-        ALOGV("execute_fde: 64-bit dwarf detected, not implemented yet");
-        return false;
-    }
-    if (!try_get_word(memory, fde + 4, &cie_offset)) {
-        return false;
-    }
-    if (cie_offset == 0) {
-        /* This is CIE. We shouldn't be here normally. */
-        cie = fde;
-        cie_length = fde_length;
-    } else {
-        /* Find CIE. */
-        /* Positive cie_offset goes backward from current field. */
-        cie = fde + 4 - cie_offset;
-        if (!try_get_word(memory, cie, &cie_length)) {
-           return false;
-        }
-        if ((int32_t)cie_length == -1) {
-           ALOGV("execute_fde: 64-bit dwarf detected, not implemented yet");
-           return false;
-        }
-        if (!try_get_word(memory, cie + 4, &cie_offset)) {
-           return false;
-        }
-        if (cie_offset != 0) {
-           ALOGV("execute_fde: can't find CIE");
-           return false;
-        }
-    }
-    ALOGV("execute_fde: FDE length: %d", fde_length);
-    ALOGV("execute_fde: CIE pointer: %x", cie);
-    ALOGV("execute_fde: CIE length: %d", cie_length);
-
-    /* Read CIE:
-       Augmentation independent:
-        1st byte is version;
-        next x bytes is /0 terminated augmentation string;
-        next x bytes is unsigned LEB128 encoded code alignment factor;
-        next x bytes is signed LEB128 encoded data alignment factor;
-        next 1 (CIE version 1) or x (CIE version 3 unsigned LEB128) bytes is return register column;
-       Augmentation dependent:
-        if 'z' next x bytes is unsigned LEB128 encoded augmentation data size;
-        if 'L' next 1 byte is LSDA encoding;
-        if 'R' next 1 byte is FDE encoding;
-        if 'S' CIE represents signal handler stack frame;
-        if 'P' next 1 byte is personality encoding folowed by personality function pointer;
-       Next x bytes is CIE program.
-    */
-
-    uint32_t c = 8;
-    if (!try_get_byte(memory, cie, &cie_info->version, &c)) {
-       return false;
-    }
-    ALOGV("execute_fde: CIE version: %d", cie_info->version);
-    uint8_t ch;
-    do {
-        if (!try_get_byte(memory, cie, &ch, &c)) {
-           return false;
-        }
-        switch (ch) {
-           case '\0': break;
-           case 'z': cie_info->aug_z = 1; break;
-           case 'L': cie_info->aug_L = 1; break;
-           case 'R': cie_info->aug_R = 1; break;
-           case 'S': cie_info->aug_S = 1; break;
-           case 'P': cie_info->aug_P = 1; break;
-           default:
-              ALOGV("execute_fde: Unrecognized CIE augmentation char: '%c'", ch);
-              return false;
-              break;
-        }
-    } while (ch);
-    if (!try_get_uleb128(memory, cie, &cie_info->code_align, &c)) {
-        return false;
-    }
-    if (!try_get_sleb128(memory, cie, &cie_info->data_align, &c)) {
-        return false;
-    }
-    if (cie_info->version >= 3) {
-        if (!try_get_uleb128(memory, cie, &cie_info->reg, &c)) {
-            return false;
-        }
-    } else {
-        if (!try_get_byte(memory, cie, (uint8_t*)&cie_info->reg, &c)) {
-            return false;
-        }
-    }
-    ALOGV("execute_fde: CIE code alignment factor: %d", cie_info->code_align);
-    ALOGV("execute_fde: CIE data alignment factor: %d", cie_info->data_align);
-    if (cie_info->aug_z) {
-        if (!try_get_uleb128(memory, cie, &cie_info->aug_z, &c)) {
-            return false;
-        }
-    }
-    if (cie_info->aug_L) {
-        if (!try_get_byte(memory, cie, &cie_info->aug_L, &c)) {
-            return false;
-        }
-    } else {
-        /* Default encoding. */
-        cie_info->aug_L = DW_EH_PE_absptr;
-    }
-    if (cie_info->aug_R) {
-        if (!try_get_byte(memory, cie, &cie_info->aug_R, &c)) {
-            return false;
-        }
-    } else {
-        /* Default encoding. */
-        cie_info->aug_R = DW_EH_PE_absptr;
-    }
-    if (cie_info->aug_P) {
-        /* Get encoding of personality routine pointer. We don't use it now. */
-        if (!try_get_byte(memory, cie, (uint8_t*)&cie_info->aug_P, &c)) {
-            return false;
-        }
-        /* Get routine pointer. */
-        if (!read_dwarf(memory, cie, &cie_info->aug_P, (uint8_t)cie_info->aug_P, &c)) {
-            return false;
-        }
-    }
-    /* CIE program. */
-    /* Length field itself (4 bytes) is not included into length. */
-    stack[0] = *dstate;
-    stack_ptr = 1;
-    while (c < cie_length + 4) {
-        if (!execute_dwarf(memory, cie, cie_info, dstate, &c, stack, &stack_ptr)) {
-           return false;
-        }
-    }
-
-    /* We went directly to CIE. Normally it shouldn't occur. */
-    if (cie == fde) return true;
-
-    /* Go back to FDE. */
-    c = 8;
-    /* Read FDE:
-       Augmentation independent:
-        next x bytes (encoded as specified in CIE) is FDE starting address;
-        next x bytes (encoded as specified in CIE) is FDE number of instructions covered;
-       Augmentation dependent:
-        if 'z' next x bytes is unsigned LEB128 encoded augmentation data size;
-        if 'L' next x bytes is LSDA pointer (encoded as specified in CIE);
-       Next x bytes is FDE program.
-     */
-    if (!read_dwarf(memory, fde, &fde_info->start, (uint8_t)cie_info->aug_R, &c)) {
-        return false;
-    }
-    dstate->loc = fde_info->start;
-    ALOGV("execute_fde: FDE start: %x", dstate->loc);
-    if (!read_dwarf(memory, fde, &fde_info->length, 0, &c)) {
-        return false;
-    }
-    ALOGV("execute_fde: FDE length: %x", fde_info->length);
-    if (cie_info->aug_z) {
-        if (!try_get_uleb128(memory, fde, &fde_info->aug_z, &c)) {
-            return false;
-        }
-    }
-    if (cie_info->aug_L && cie_info->aug_L != DW_EH_PE_omit) {
-        if (!read_dwarf(memory, fde, &fde_info->aug_L, cie_info->aug_L, &c)) {
-            return false;
-        }
-    }
-    /* FDE program. */
-    /* Length field itself (4 bytes) is not included into length. */
-    /* Save CIE state as 0 element of stack. Used by DW_CFA_restore. */
-    stack[0] = *dstate;
-    stack_ptr = 1;
-    while (c < fde_length + 4 && state->reg[DWARF_EIP] >= dstate->loc) {
-        if (!execute_dwarf(memory, fde, cie_info, dstate, &c, stack, &stack_ptr)) {
-           return false;
-        }
-        ALOGV("IP: %x, LOC: %x", state->reg[DWARF_EIP], dstate->loc);
-    }
-
-    return update_state(memory, state, dstate);
-}
-
-static ssize_t unwind_backtrace_common(const memory_t* memory,
-        const map_info_t* map_info_list,
-        unwind_state_t* state, backtrace_frame_t* backtrace,
-        size_t ignore_depth, size_t max_depth) {
-
-    size_t ignored_frames = 0;
-    size_t returned_frames = 0;
-
-    ALOGV("Unwinding tid: %d", memory->tid);
-    ALOGV("IP: %x", state->reg[DWARF_EIP]);
-    ALOGV("BP: %x", state->reg[DWARF_EBP]);
-    ALOGV("SP: %x", state->reg[DWARF_ESP]);
-
-    for (size_t index = 0; returned_frames < max_depth; index++) {
-        uintptr_t fde = find_fde(memory, map_info_list, state->reg[DWARF_EIP]);
-        /* FDE is not found, it may happen if stack is corrupted or calling wrong adress.
-           Getting return address from stack.
-        */
-        if (!fde) {
-            uint32_t ip;
-            ALOGV("trying to restore registers from stack");
-            if (!try_get_word(memory, state->reg[DWARF_EBP] + 4, &ip) ||
-                ip == state->reg[DWARF_EIP]) {
-                ALOGV("can't get IP from stack");
-                break;
-            }
-            /* We've been able to get IP from stack so recording the frame before continue. */
-            backtrace_frame_t* frame = add_backtrace_entry(
-                    index ? rewind_pc_arch(memory, state->reg[DWARF_EIP]) : state->reg[DWARF_EIP],
-                    backtrace, ignore_depth, max_depth,
-                    &ignored_frames, &returned_frames);
-            state->reg[DWARF_EIP] = ip;
-            state->reg[DWARF_ESP] = state->reg[DWARF_EBP] + 8;
-            if (!try_get_word(memory, state->reg[DWARF_EBP], &state->reg[DWARF_EBP])) {
-                ALOGV("can't get EBP from stack");
-                break;
-            }
-            ALOGV("restore IP: %x", state->reg[DWARF_EIP]);
-            ALOGV("restore BP: %x", state->reg[DWARF_EBP]);
-            ALOGV("restore SP: %x", state->reg[DWARF_ESP]);
-            continue;
-        }
-        backtrace_frame_t* frame = add_backtrace_entry(
-                index ? rewind_pc_arch(memory, state->reg[DWARF_EIP]) : state->reg[DWARF_EIP],
-                backtrace, ignore_depth, max_depth,
-                &ignored_frames, &returned_frames);
-
-        uint32_t stack_top = state->reg[DWARF_ESP];
-
-        if (!execute_fde(memory, fde, state)) break;
-
-        if (frame) {
-            frame->stack_top = stack_top;
-            if (stack_top < state->reg[DWARF_ESP]) {
-                frame->stack_size = state->reg[DWARF_ESP] - stack_top;
-            }
-        }
-        ALOGV("Stack: 0x%x ... 0x%x - %d bytes", frame->stack_top, state->reg[DWARF_ESP], frame->stack_size);
-    }
-    return returned_frames;
-}
-
-ssize_t unwind_backtrace_signal_arch(siginfo_t* siginfo __attribute__((unused)), void* sigcontext,
-        const map_info_t* map_info_list,
-        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) {
-    const ucontext_t* uc = (const ucontext_t*)sigcontext;
-
-    unwind_state_t state;
-#if defined(__APPLE__)
-    state.reg[DWARF_EBP] = uc->uc_mcontext->__ss.__ebp;
-    state.reg[DWARF_ESP] = uc->uc_mcontext->__ss.__esp;
-    state.reg[DWARF_EIP] = uc->uc_mcontext->__ss.__eip;
-#else
-    state.reg[DWARF_EBP] = uc->uc_mcontext.gregs[REG_EBP];
-    state.reg[DWARF_ESP] = uc->uc_mcontext.gregs[REG_ESP];
-    state.reg[DWARF_EIP] = uc->uc_mcontext.gregs[REG_EIP];
-#endif
-
-    memory_t memory;
-    init_memory(&memory, map_info_list);
-    return unwind_backtrace_common(&memory, map_info_list,
-            &state, backtrace, ignore_depth, max_depth);
-}
-
-ssize_t unwind_backtrace_ptrace_arch(pid_t tid, const ptrace_context_t* context,
-        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) {
-#if defined(__APPLE__)
-    return -1;
-#else
-    pt_regs_x86_t regs;
-    if (ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
-        return -1;
-    }
-
-    unwind_state_t state;
-    state.reg[DWARF_EBP] = regs.ebp;
-    state.reg[DWARF_EIP] = regs.eip;
-    state.reg[DWARF_ESP] = regs.esp;
-
-    memory_t memory;
-    init_memory_ptrace(&memory, tid);
-    return unwind_backtrace_common(&memory, context->map_info_list,
-            &state, backtrace, ignore_depth, max_depth);
-#endif
-}
diff --git a/libcorkscrew/arch-x86/dwarf.h b/libcorkscrew/arch-x86/dwarf.h
deleted file mode 100755
index 962fc55..0000000
--- a/libcorkscrew/arch-x86/dwarf.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-/*
- * Dwarf2 data encoding flags.
- */
-
-#define DW_EH_PE_absptr         0x00
-#define DW_EH_PE_omit           0xff
-#define DW_EH_PE_uleb128        0x01
-#define DW_EH_PE_udata2         0x02
-#define DW_EH_PE_udata4         0x03
-#define DW_EH_PE_udata8         0x04
-#define DW_EH_PE_sleb128        0x09
-#define DW_EH_PE_sdata2         0x0A
-#define DW_EH_PE_sdata4         0x0B
-#define DW_EH_PE_sdata8         0x0C
-#define DW_EH_PE_signed         0x08
-#define DW_EH_PE_pcrel          0x10
-#define DW_EH_PE_textrel        0x20
-#define DW_EH_PE_datarel        0x30
-#define DW_EH_PE_funcrel        0x40
-#define DW_EH_PE_aligned        0x50
-#define DW_EH_PE_indirect       0x80
-
-/*
- * Dwarf2 call frame instructions.
- */
-
-typedef enum {
-    DW_CFA_advance_loc = 0x40,
-    DW_CFA_offset = 0x80,
-    DW_CFA_restore = 0xc0,
-    DW_CFA_nop = 0x00,
-    DW_CFA_set_loc = 0x01,
-    DW_CFA_advance_loc1 = 0x02,
-    DW_CFA_advance_loc2 = 0x03,
-    DW_CFA_advance_loc4 = 0x04,
-    DW_CFA_offset_extended = 0x05,
-    DW_CFA_restore_extended = 0x06,
-    DW_CFA_undefined = 0x07,
-    DW_CFA_same_value = 0x08,
-    DW_CFA_register = 0x09,
-    DW_CFA_remember_state = 0x0a,
-    DW_CFA_restore_state = 0x0b,
-    DW_CFA_def_cfa = 0x0c,
-    DW_CFA_def_cfa_register = 0x0d,
-    DW_CFA_def_cfa_offset = 0x0e
-} dwarf_CFA;
-
-/*
- * eh_frame_hdr information.
-*/
-
-typedef struct {
-      uint8_t version;
-      uint8_t eh_frame_ptr_enc;
-      uint8_t fde_count_enc;
-      uint8_t fde_table_enc;
-      uintptr_t eh_frame_ptr;
-      uint32_t fde_count;
-} eh_frame_hdr_info_t;
-
-/*
- * CIE information.
-*/
-
-typedef struct {
-      uint8_t version;
-      uint32_t code_align;
-      uint32_t data_align;
-      uint32_t reg;
-      uint32_t aug_z;
-      uint8_t aug_L;
-      uint8_t aug_R;
-      uint8_t aug_S;
-      uint32_t aug_P;
-} cie_info_t;
-
-/*
- * FDE information.
-*/
-
-typedef struct {
-      uint32_t start;
-      uint32_t length; // number of instructions covered by FDE
-      uint32_t aug_z;
-      uint32_t aug_L;
-} fde_info_t;
-
-/*
- * Dwarf state.
-*/
-
-/* Stack of states: required for DW_CFA_remember_state/DW_CFA_restore_state
-   30 should be enough */
-#define DWARF_STATES_STACK 30
-
-typedef struct {
-    char rule;         // rule: o - offset(value); r - register(value)
-    uint32_t value;    // value
-} reg_rule_t;
-
-/* Dwarf preserved number of registers for x86. */
-
-#define DWARF_REGISTERS 17
-
-typedef struct {
-    uintptr_t loc;     // location (ip)
-    uint8_t cfa_reg;   // index of register where CFA location stored
-    intptr_t cfa_off;  // offset
-    reg_rule_t regs[DWARF_REGISTERS]; // dwarf preserved registers for x86
-} dwarf_state_t;
-
-/* DWARF registers we are caring about. */
-
-#define DWARF_EAX     0
-#define DWARF_ECX     1
-#define DWARF_EDX     2
-#define DWARF_EBX     3
-#define DWARF_ESP     4
-#define DWARF_EBP     5
-#define DWARF_ESI     6
-#define DWARF_EDI     7
-#define DWARF_EIP     8
-
-
diff --git a/libcorkscrew/arch-x86/ptrace-x86.c b/libcorkscrew/arch-x86/ptrace-x86.c
deleted file mode 100755
index 9c49b93..0000000
--- a/libcorkscrew/arch-x86/ptrace-x86.c
+++ /dev/null
@@ -1,64 +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.
- */
-
-#define LOG_TAG "Corkscrew"
-//#define LOG_NDEBUG 0
-
-#include "../ptrace-arch.h"
-
-#include <stddef.h>
-#include <elf.h>
-#include <cutils/log.h>
-
-static void load_eh_frame_hdr(pid_t pid, map_info_t* mi, uintptr_t *eh_frame_hdr) {
-    uint32_t elf_phoff;
-    uint32_t elf_phentsize_ehsize;
-    uint32_t elf_shentsize_phnum;
-    if (try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_phoff), &elf_phoff)
-            && try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_ehsize),
-                    &elf_phentsize_ehsize)
-            && try_get_word_ptrace(pid, mi->start + offsetof(Elf32_Ehdr, e_phnum),
-                    &elf_shentsize_phnum)) {
-        uint32_t elf_phentsize = elf_phentsize_ehsize >> 16;
-        uint32_t elf_phnum = elf_shentsize_phnum & 0xffff;
-        for (uint32_t i = 0; i < elf_phnum; i++) {
-            uintptr_t elf_phdr = mi->start + elf_phoff + i * elf_phentsize;
-            uint32_t elf_phdr_type;
-            if (!try_get_word_ptrace(pid, elf_phdr + offsetof(Elf32_Phdr, p_type), &elf_phdr_type)) {
-                break;
-            }
-            if (elf_phdr_type == PT_GNU_EH_FRAME) {
-                uint32_t elf_phdr_offset;
-                if (!try_get_word_ptrace(pid, elf_phdr + offsetof(Elf32_Phdr, p_offset),
-                        &elf_phdr_offset)) {
-                    break;
-                }
-                *eh_frame_hdr = mi->start + elf_phdr_offset;
-                ALOGV("Parsed .eh_frame_hdr info for %s: start=0x%08x", mi->name, *eh_frame_hdr);
-                return;
-            }
-        }
-    }
-    *eh_frame_hdr = 0;
-}
-
-void load_ptrace_map_info_data_arch(pid_t pid, map_info_t* mi, map_info_data_t* data) {
-    load_eh_frame_hdr(pid, mi, &data->eh_frame_hdr);
-}
-
-void free_ptrace_map_info_data_arch(map_info_t* mi __attribute__((unused)),
-                                    map_info_data_t* data __attribute__((unused))) {
-}
diff --git a/libcorkscrew/backtrace-arch.h b/libcorkscrew/backtrace-arch.h
deleted file mode 100644
index a46f80b..0000000
--- a/libcorkscrew/backtrace-arch.h
+++ /dev/null
@@ -1,45 +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.
- */
-
-/* Architecture dependent functions. */
-
-#ifndef _CORKSCREW_BACKTRACE_ARCH_H
-#define _CORKSCREW_BACKTRACE_ARCH_H
-
-#include "ptrace-arch.h"
-#include <corkscrew/backtrace.h>
-
-#include <signal.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Rewind the program counter by one instruction. */
-uintptr_t rewind_pc_arch(const memory_t* memory, uintptr_t pc);
-
-ssize_t unwind_backtrace_signal_arch(siginfo_t* siginfo, void* sigcontext,
-        const map_info_t* map_info_list,
-        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth);
-
-ssize_t unwind_backtrace_ptrace_arch(pid_t tid, const ptrace_context_t* context,
-        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _CORKSCREW_BACKTRACE_ARCH_H
diff --git a/libcorkscrew/backtrace-helper.c b/libcorkscrew/backtrace-helper.c
deleted file mode 100644
index bf9d3f3..0000000
--- a/libcorkscrew/backtrace-helper.c
+++ /dev/null
@@ -1,40 +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.
- */
-
-#define LOG_TAG "Corkscrew"
-//#define LOG_NDEBUG 0
-
-#include "backtrace-helper.h"
-
-#include <cutils/log.h>
-
-backtrace_frame_t* add_backtrace_entry(uintptr_t pc, backtrace_frame_t* backtrace,
-        size_t ignore_depth, size_t max_depth,
-        size_t* ignored_frames, size_t* returned_frames) {
-    if (*ignored_frames < ignore_depth) {
-        *ignored_frames += 1;
-        return NULL;
-    }
-    if (*returned_frames >= max_depth) {
-        return NULL;
-    }
-    backtrace_frame_t* frame = &backtrace[*returned_frames];
-    frame->absolute_pc = pc;
-    frame->stack_top = 0;
-    frame->stack_size = 0;
-    *returned_frames += 1;
-    return frame;
-}
diff --git a/libcorkscrew/backtrace-helper.h b/libcorkscrew/backtrace-helper.h
deleted file mode 100644
index 4d8a874..0000000
--- a/libcorkscrew/backtrace-helper.h
+++ /dev/null
@@ -1,43 +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.
- */
-
-/* Backtrace helper functions. */
-
-#ifndef _CORKSCREW_BACKTRACE_HELPER_H
-#define _CORKSCREW_BACKTRACE_HELPER_H
-
-#include <corkscrew/backtrace.h>
-#include <sys/types.h>
-#include <stdbool.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Add a program counter to a backtrace if it will fit.
- * Returns the newly added frame, or NULL if none.
- */
-backtrace_frame_t* add_backtrace_entry(uintptr_t pc,
-        backtrace_frame_t* backtrace,
-        size_t ignore_depth, size_t max_depth,
-        size_t* ignored_frames, size_t* returned_frames);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _CORKSCREW_BACKTRACE_HELPER_H
diff --git a/libcorkscrew/backtrace.c b/libcorkscrew/backtrace.c
deleted file mode 100644
index f1dd61d..0000000
--- a/libcorkscrew/backtrace.c
+++ /dev/null
@@ -1,335 +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.
- */
-
-#define LOG_TAG "Corkscrew"
-//#define LOG_NDEBUG 0
-
-#include "backtrace-arch.h"
-#include "backtrace-helper.h"
-#include "ptrace-arch.h"
-#include <corkscrew/map_info.h>
-#include <corkscrew/symbol_table.h>
-#include <corkscrew/ptrace.h>
-#include <corkscrew/demangle.h>
-
-#include <unistd.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-#include <unwind.h>
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-
-#define __USE_GNU // For dladdr(3) in glibc.
-#include <dlfcn.h>
-
-#if defined(__BIONIC__)
-
-// Bionic implements and exports gettid but only implements tgkill.
-extern int tgkill(int tgid, int tid, int sig);
-
-#elif defined(__APPLE__)
-
-#include <sys/syscall.h>
-
-// Mac OS >= 10.6 has a system call equivalent to Linux's gettid().
-static pid_t gettid() {
-  return syscall(SYS_thread_selfid);
-}
-
-#else
-
-// glibc doesn't implement or export either gettid or tgkill.
-
-#include <unistd.h>
-#include <sys/syscall.h>
-
-static pid_t gettid() {
-  return syscall(__NR_gettid);
-}
-
-static int tgkill(int tgid, int tid, int sig) {
-  return syscall(__NR_tgkill, tgid, tid, sig);
-}
-
-#endif
-
-typedef struct {
-    backtrace_frame_t* backtrace;
-    size_t ignore_depth;
-    size_t max_depth;
-    size_t ignored_frames;
-    size_t returned_frames;
-    memory_t memory;
-} backtrace_state_t;
-
-static _Unwind_Reason_Code unwind_backtrace_callback(struct _Unwind_Context* context, void* arg) {
-    backtrace_state_t* state = (backtrace_state_t*)arg;
-    uintptr_t pc = _Unwind_GetIP(context);
-    if (pc) {
-        // TODO: Get information about the stack layout from the _Unwind_Context.
-        //       This will require a new architecture-specific function to query
-        //       the appropriate registers.  Current callers of unwind_backtrace
-        //       don't need this information, so we won't bother collecting it just yet.
-        add_backtrace_entry(rewind_pc_arch(&state->memory, pc), state->backtrace,
-                state->ignore_depth, state->max_depth,
-                &state->ignored_frames, &state->returned_frames);
-    }
-    return state->returned_frames < state->max_depth ? _URC_NO_REASON : _URC_END_OF_STACK;
-}
-
-ssize_t unwind_backtrace(backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) {
-    ALOGV("Unwinding current thread %d.", gettid());
-
-    map_info_t* milist = acquire_my_map_info_list();
-
-    backtrace_state_t state;
-    state.backtrace = backtrace;
-    state.ignore_depth = ignore_depth;
-    state.max_depth = max_depth;
-    state.ignored_frames = 0;
-    state.returned_frames = 0;
-    init_memory(&state.memory, milist);
-
-    _Unwind_Reason_Code rc = _Unwind_Backtrace(unwind_backtrace_callback, &state);
-
-    release_my_map_info_list(milist);
-
-    if (state.returned_frames) {
-        return state.returned_frames;
-    }
-    return rc == _URC_END_OF_STACK ? 0 : -1;
-}
-
-#ifdef CORKSCREW_HAVE_ARCH
-static const int32_t STATE_DUMPING = -1;
-static const int32_t STATE_DONE = -2;
-static const int32_t STATE_CANCEL = -3;
-
-static pthread_mutex_t g_unwind_signal_mutex = PTHREAD_MUTEX_INITIALIZER;
-static volatile struct {
-    int32_t tid_state;
-    const map_info_t* map_info_list;
-    backtrace_frame_t* backtrace;
-    size_t ignore_depth;
-    size_t max_depth;
-    size_t returned_frames;
-} g_unwind_signal_state;
-
-static void unwind_backtrace_thread_signal_handler(int n __attribute__((unused)), siginfo_t* siginfo, void* sigcontext) {
-    if (!android_atomic_acquire_cas(gettid(), STATE_DUMPING, &g_unwind_signal_state.tid_state)) {
-        g_unwind_signal_state.returned_frames = unwind_backtrace_signal_arch(
-                siginfo, sigcontext,
-                g_unwind_signal_state.map_info_list,
-                g_unwind_signal_state.backtrace,
-                g_unwind_signal_state.ignore_depth,
-                g_unwind_signal_state.max_depth);
-        android_atomic_release_store(STATE_DONE, &g_unwind_signal_state.tid_state);
-    } else {
-        ALOGV("Received spurious SIGURG on thread %d that was intended for thread %d.",
-                gettid(), android_atomic_acquire_load(&g_unwind_signal_state.tid_state));
-    }
-}
-#endif
-
-ssize_t unwind_backtrace_thread(pid_t tid, backtrace_frame_t* backtrace,
-        size_t ignore_depth, size_t max_depth) {
-    if (tid == gettid()) {
-        return unwind_backtrace(backtrace, ignore_depth + 1, max_depth);
-    }
-
-    ALOGV("Unwinding thread %d from thread %d.", tid, gettid());
-
-    // TODO: there's no tgkill(2) on Mac OS, so we'd either need the
-    // mach_port_t or the pthread_t rather than the tid.
-#if defined(CORKSCREW_HAVE_ARCH) && !defined(__APPLE__)
-    struct sigaction act;
-    struct sigaction oact;
-    memset(&act, 0, sizeof(act));
-    act.sa_sigaction = unwind_backtrace_thread_signal_handler;
-    act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
-    sigemptyset(&act.sa_mask);
-
-    pthread_mutex_lock(&g_unwind_signal_mutex);
-    map_info_t* milist = acquire_my_map_info_list();
-
-    ssize_t frames = -1;
-    if (!sigaction(SIGURG, &act, &oact)) {
-        g_unwind_signal_state.map_info_list = milist;
-        g_unwind_signal_state.backtrace = backtrace;
-        g_unwind_signal_state.ignore_depth = ignore_depth;
-        g_unwind_signal_state.max_depth = max_depth;
-        g_unwind_signal_state.returned_frames = 0;
-        android_atomic_release_store(tid, &g_unwind_signal_state.tid_state);
-
-        // Signal the specific thread that we want to dump.
-        int32_t tid_state = tid;
-        if (tgkill(getpid(), tid, SIGURG)) {
-            ALOGV("Failed to send SIGURG to thread %d.", tid);
-        } else {
-            // Wait for the other thread to start dumping the stack, or time out.
-            int wait_millis = 250;
-            for (;;) {
-                tid_state = android_atomic_acquire_load(&g_unwind_signal_state.tid_state);
-                if (tid_state != tid) {
-                    break;
-                }
-                if (wait_millis--) {
-                    ALOGV("Waiting for thread %d to start dumping the stack...", tid);
-                    usleep(1000);
-                } else {
-                    ALOGV("Timed out waiting for thread %d to start dumping the stack.", tid);
-                    break;
-                }
-            }
-        }
-
-        // Try to cancel the dump if it has not started yet.
-        if (tid_state == tid) {
-            if (!android_atomic_acquire_cas(tid, STATE_CANCEL, &g_unwind_signal_state.tid_state)) {
-                ALOGV("Canceled thread %d stack dump.", tid);
-                tid_state = STATE_CANCEL;
-            } else {
-                tid_state = android_atomic_acquire_load(&g_unwind_signal_state.tid_state);
-            }
-        }
-
-        // Wait indefinitely for the dump to finish or be canceled.
-        // We cannot apply a timeout here because the other thread is accessing state that
-        // is owned by this thread, such as milist.  It should not take very
-        // long to take the dump once started.
-        while (tid_state == STATE_DUMPING) {
-            ALOGV("Waiting for thread %d to finish dumping the stack...", tid);
-            usleep(1000);
-            tid_state = android_atomic_acquire_load(&g_unwind_signal_state.tid_state);
-        }
-
-        if (tid_state == STATE_DONE) {
-            frames = g_unwind_signal_state.returned_frames;
-        }
-
-        sigaction(SIGURG, &oact, NULL);
-    }
-
-    release_my_map_info_list(milist);
-    pthread_mutex_unlock(&g_unwind_signal_mutex);
-    return frames;
-#else
-    return -1;
-#endif
-}
-
-ssize_t unwind_backtrace_ptrace(pid_t tid, const ptrace_context_t* context,
-        backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) {
-#ifdef CORKSCREW_HAVE_ARCH
-    return unwind_backtrace_ptrace_arch(tid, context, backtrace, ignore_depth, max_depth);
-#else
-    return -1;
-#endif
-}
-
-static void init_backtrace_symbol(backtrace_symbol_t* symbol, uintptr_t pc) {
-    symbol->relative_pc = pc;
-    symbol->relative_symbol_addr = 0;
-    symbol->map_name = NULL;
-    symbol->symbol_name = NULL;
-    symbol->demangled_name = NULL;
-}
-
-void get_backtrace_symbols(const backtrace_frame_t* backtrace, size_t frames,
-        backtrace_symbol_t* backtrace_symbols) {
-    map_info_t* milist = acquire_my_map_info_list();
-    for (size_t i = 0; i < frames; i++) {
-        const backtrace_frame_t* frame = &backtrace[i];
-        backtrace_symbol_t* symbol = &backtrace_symbols[i];
-        init_backtrace_symbol(symbol, frame->absolute_pc);
-
-        const map_info_t* mi = find_map_info(milist, frame->absolute_pc);
-        if (mi) {
-            symbol->relative_pc = frame->absolute_pc - mi->start;
-            if (mi->name[0]) {
-                symbol->map_name = strdup(mi->name);
-            }
-            Dl_info info;
-            if (dladdr((const void*)frame->absolute_pc, &info) && info.dli_sname) {
-                symbol->relative_symbol_addr = (uintptr_t)info.dli_saddr
-                        - (uintptr_t)info.dli_fbase;
-                symbol->symbol_name = strdup(info.dli_sname);
-                symbol->demangled_name = demangle_symbol_name(symbol->symbol_name);
-            }
-        }
-    }
-    release_my_map_info_list(milist);
-}
-
-void get_backtrace_symbols_ptrace(const ptrace_context_t* context,
-        const backtrace_frame_t* backtrace, size_t frames,
-        backtrace_symbol_t* backtrace_symbols) {
-    for (size_t i = 0; i < frames; i++) {
-        const backtrace_frame_t* frame = &backtrace[i];
-        backtrace_symbol_t* symbol = &backtrace_symbols[i];
-        init_backtrace_symbol(symbol, frame->absolute_pc);
-
-        const map_info_t* mi;
-        const symbol_t* s;
-        find_symbol_ptrace(context, frame->absolute_pc, &mi, &s);
-        if (mi) {
-            symbol->relative_pc = frame->absolute_pc - mi->start;
-            if (mi->name[0]) {
-                symbol->map_name = strdup(mi->name);
-            }
-        }
-        if (s) {
-            symbol->relative_symbol_addr = s->start;
-            symbol->symbol_name = strdup(s->name);
-            symbol->demangled_name = demangle_symbol_name(symbol->symbol_name);
-        }
-    }
-}
-
-void free_backtrace_symbols(backtrace_symbol_t* backtrace_symbols, size_t frames) {
-    for (size_t i = 0; i < frames; i++) {
-        backtrace_symbol_t* symbol = &backtrace_symbols[i];
-        free(symbol->map_name);
-        free(symbol->symbol_name);
-        free(symbol->demangled_name);
-        init_backtrace_symbol(symbol, 0);
-    }
-}
-
-void format_backtrace_line(unsigned frameNumber, const backtrace_frame_t* frame __attribute__((unused)),
-        const backtrace_symbol_t* symbol, char* buffer, size_t bufferSize) {
-    const char* mapName = symbol->map_name ? symbol->map_name : "<unknown>";
-    const char* symbolName = symbol->demangled_name ? symbol->demangled_name : symbol->symbol_name;
-    int fieldWidth = (bufferSize - 80) / 2;
-    if (symbolName) {
-        uint32_t pc_offset = symbol->relative_pc - symbol->relative_symbol_addr;
-        if (pc_offset) {
-            snprintf(buffer, bufferSize, "#%02u  pc %08x  %.*s (%.*s+%u)",
-                    frameNumber, (unsigned int) symbol->relative_pc,
-                    fieldWidth, mapName, fieldWidth, symbolName, pc_offset);
-        } else {
-            snprintf(buffer, bufferSize, "#%02u  pc %08x  %.*s (%.*s)",
-                    frameNumber, (unsigned int) symbol->relative_pc,
-                    fieldWidth, mapName, fieldWidth, symbolName);
-        }
-    } else {
-        snprintf(buffer, bufferSize, "#%02u  pc %08x  %.*s",
-                frameNumber, (unsigned int) symbol->relative_pc,
-                fieldWidth, mapName);
-    }
-}
diff --git a/libcorkscrew/demangle.c b/libcorkscrew/demangle.c
deleted file mode 100644
index 30ab1b0..0000000
--- a/libcorkscrew/demangle.c
+++ /dev/null
@@ -1,36 +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.
- */
-
-#define LOG_TAG "Corkscrew"
-//#define LOG_NDEBUG 0
-
-#include <corkscrew/demangle.h>
-
-#include <cutils/log.h>
-
-extern char *__cxa_demangle (const char *mangled, char *buf, size_t *len,
-                             int *status);
-
-char* demangle_symbol_name(const char* name) {
-#if defined(__APPLE__)
-    // Mac OS' __cxa_demangle demangles "f" as "float"; last tested on 10.7.
-    if (name != NULL && name[0] != '_') {
-        return NULL;
-    }
-#endif
-    // __cxa_demangle handles NULL by returning NULL
-    return __cxa_demangle(name, 0, 0, 0);
-}
diff --git a/libcorkscrew/map_info.c b/libcorkscrew/map_info.c
deleted file mode 100644
index 93dffbf..0000000
--- a/libcorkscrew/map_info.c
+++ /dev/null
@@ -1,279 +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.
- */
-
-#define LOG_TAG "Corkscrew"
-//#define LOG_NDEBUG 0
-
-#include <corkscrew/map_info.h>
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <cutils/log.h>
-#include <sys/time.h>
-
-#if defined(__APPLE__)
-
-// Mac OS vmmap(1) output:
-// __TEXT                 0009f000-000a1000 [    8K     8K] r-x/rwx SM=COW  /Volumes/android/dalvik-dev/out/host/darwin-x86/bin/libcorkscrew_test\n
-// 012345678901234567890123456789012345678901234567890123456789
-// 0         1         2         3         4         5
-static map_info_t* parse_vmmap_line(const char* line) {
-    unsigned long int start;
-    unsigned long int end;
-    char permissions[4];
-    int name_pos;
-    if (sscanf(line, "%*21c %lx-%lx [%*13c] %3c/%*3c SM=%*3c  %n",
-               &start, &end, permissions, &name_pos) != 3) {
-        return NULL;
-    }
-
-    const char* name = line + name_pos;
-    size_t name_len = strlen(name);
-
-    map_info_t* mi = calloc(1, sizeof(map_info_t) + name_len);
-    if (mi != NULL) {
-        mi->start = start;
-        mi->end = end;
-        mi->is_readable = permissions[0] == 'r';
-        mi->is_writable = permissions[1] == 'w';
-        mi->is_executable = permissions[2] == 'x';
-        mi->data = NULL;
-        memcpy(mi->name, name, name_len);
-        mi->name[name_len - 1] = '\0';
-        ALOGV("Parsed map: start=0x%08x, end=0x%08x, "
-              "is_readable=%d, is_writable=%d is_executable=%d, name=%s",
-              mi->start, mi->end,
-              mi->is_readable, mi->is_writable, mi->is_executable, mi->name);
-    }
-    return mi;
-}
-
-map_info_t* load_map_info_list(pid_t pid) {
-    char cmd[1024];
-    snprintf(cmd, sizeof(cmd), "vmmap -w -resident -submap -allSplitLibs -interleaved %d", pid);
-    FILE* fp = popen(cmd, "r");
-    if (fp == NULL) {
-        return NULL;
-    }
-
-    char line[1024];
-    map_info_t* milist = NULL;
-    while (fgets(line, sizeof(line), fp) != NULL) {
-        map_info_t* mi = parse_vmmap_line(line);
-        if (mi != NULL) {
-            mi->next = milist;
-            milist = mi;
-        }
-    }
-    pclose(fp);
-    return milist;
-}
-
-#else
-
-// Linux /proc/<pid>/maps lines:
-// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419   /system/lib/libcomposer.so\n
-// 012345678901234567890123456789012345678901234567890123456789
-// 0         1         2         3         4         5
-static map_info_t* parse_maps_line(const char* line)
-{
-    unsigned long int start;
-    unsigned long int end;
-    char permissions[5];
-    int name_pos;
-    if (sscanf(line, "%lx-%lx %4s %*x %*x:%*x %*d%n", &start, &end,
-            permissions, &name_pos) != 3) {
-        return NULL;
-    }
-
-    while (isspace(line[name_pos])) {
-        name_pos += 1;
-    }
-    const char* name = line + name_pos;
-    size_t name_len = strlen(name);
-    if (name_len && name[name_len - 1] == '\n') {
-        name_len -= 1;
-    }
-
-    map_info_t* mi = calloc(1, sizeof(map_info_t) + name_len + 1);
-    if (mi) {
-        mi->start = start;
-        mi->end = end;
-        mi->is_readable = strlen(permissions) == 4 && permissions[0] == 'r';
-        mi->is_writable = strlen(permissions) == 4 && permissions[1] == 'w';
-        mi->is_executable = strlen(permissions) == 4 && permissions[2] == 'x';
-        mi->data = NULL;
-        memcpy(mi->name, name, name_len);
-        mi->name[name_len] = '\0';
-        ALOGV("Parsed map: start=0x%08x, end=0x%08x, "
-              "is_readable=%d, is_writable=%d, is_executable=%d, name=%s",
-              mi->start, mi->end,
-              mi->is_readable, mi->is_writable, mi->is_executable, mi->name);
-    }
-    return mi;
-}
-
-map_info_t* load_map_info_list(pid_t tid) {
-    char path[PATH_MAX];
-    char line[1024];
-    FILE* fp;
-    map_info_t* milist = NULL;
-
-    snprintf(path, PATH_MAX, "/proc/%d/maps", tid);
-    fp = fopen(path, "r");
-    if (fp) {
-        while(fgets(line, sizeof(line), fp)) {
-            map_info_t* mi = parse_maps_line(line);
-            if (mi) {
-                mi->next = milist;
-                milist = mi;
-            }
-        }
-        fclose(fp);
-    }
-    return milist;
-}
-
-#endif
-
-void free_map_info_list(map_info_t* milist) {
-    while (milist) {
-        map_info_t* next = milist->next;
-        free(milist);
-        milist = next;
-    }
-}
-
-const map_info_t* find_map_info(const map_info_t* milist, uintptr_t addr) {
-    const map_info_t* mi = milist;
-    while (mi && !(addr >= mi->start && addr < mi->end)) {
-        mi = mi->next;
-    }
-    return mi;
-}
-
-bool is_readable_map(const map_info_t* milist, uintptr_t addr) {
-    const map_info_t* mi = find_map_info(milist, addr);
-    return mi && mi->is_readable;
-}
-
-bool is_writable_map(const map_info_t* milist, uintptr_t addr) {
-    const map_info_t* mi = find_map_info(milist, addr);
-    return mi && mi->is_writable;
-}
-
-bool is_executable_map(const map_info_t* milist, uintptr_t addr) {
-    const map_info_t* mi = find_map_info(milist, addr);
-    return mi && mi->is_executable;
-}
-
-static pthread_mutex_t g_my_map_info_list_mutex = PTHREAD_MUTEX_INITIALIZER;
-static map_info_t* g_my_map_info_list = NULL;
-
-static const int64_t MAX_CACHE_AGE = 5 * 1000 * 1000000LL;
-
-typedef struct {
-    uint32_t refs;
-    int64_t timestamp;
-} my_map_info_data_t;
-
-static int64_t now_ns() {
-#if defined(HAVE_POSIX_CLOCKS)
-    struct timespec t;
-    t.tv_sec = t.tv_nsec = 0;
-    clock_gettime(CLOCK_MONOTONIC, &t);
-    return t.tv_sec * 1000000000LL + t.tv_nsec;
-#else
-    struct timeval t;
-    gettimeofday(&t, NULL);
-    return t.tv_sec * 1000000000LL + t.tv_usec * 1000LL;
-#endif
-}
-
-static void dec_ref(map_info_t* milist, my_map_info_data_t* data) {
-    if (!--data->refs) {
-        ALOGV("Freed my_map_info_list %p.", milist);
-        free(data);
-        free_map_info_list(milist);
-    }
-}
-
-map_info_t* acquire_my_map_info_list() {
-    pthread_mutex_lock(&g_my_map_info_list_mutex);
-
-    int64_t time = now_ns();
-    if (g_my_map_info_list != NULL) {
-        my_map_info_data_t* data = (my_map_info_data_t*)g_my_map_info_list->data;
-        int64_t age = time - data->timestamp;
-        if (age >= MAX_CACHE_AGE) {
-            ALOGV("Invalidated my_map_info_list %p, age=%lld.", g_my_map_info_list, age);
-            dec_ref(g_my_map_info_list, data);
-            g_my_map_info_list = NULL;
-        } else {
-            ALOGV("Reusing my_map_info_list %p, age=%lld.", g_my_map_info_list, age);
-        }
-    }
-
-    if (g_my_map_info_list == NULL) {
-        my_map_info_data_t* data = (my_map_info_data_t*)malloc(sizeof(my_map_info_data_t));
-        g_my_map_info_list = load_map_info_list(getpid());
-        if (g_my_map_info_list != NULL) {
-            ALOGV("Loaded my_map_info_list %p.", g_my_map_info_list);
-            g_my_map_info_list->data = data;
-            data->refs = 1;
-            data->timestamp = time;
-        } else {
-            free(data);
-        }
-    }
-
-    map_info_t* milist = g_my_map_info_list;
-    if (milist) {
-        my_map_info_data_t* data = (my_map_info_data_t*)g_my_map_info_list->data;
-        data->refs += 1;
-    }
-
-    pthread_mutex_unlock(&g_my_map_info_list_mutex);
-    return milist;
-}
-
-void release_my_map_info_list(map_info_t* milist) {
-    if (milist) {
-        pthread_mutex_lock(&g_my_map_info_list_mutex);
-
-        my_map_info_data_t* data = (my_map_info_data_t*)milist->data;
-        dec_ref(milist, data);
-
-        pthread_mutex_unlock(&g_my_map_info_list_mutex);
-    }
-}
-
-void flush_my_map_info_list() {
-    pthread_mutex_lock(&g_my_map_info_list_mutex);
-
-    if (g_my_map_info_list != NULL) {
-        my_map_info_data_t* data = (my_map_info_data_t*) g_my_map_info_list->data;
-        dec_ref(g_my_map_info_list, data);
-        g_my_map_info_list = NULL;
-    }
-
-    pthread_mutex_unlock(&g_my_map_info_list_mutex);
-}
diff --git a/libcorkscrew/ptrace-arch.h b/libcorkscrew/ptrace-arch.h
deleted file mode 100755
index 0bcff63..0000000
--- a/libcorkscrew/ptrace-arch.h
+++ /dev/null
@@ -1,51 +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.
- */
-
-/* Architecture dependent functions. */
-
-#ifndef _CORKSCREW_PTRACE_ARCH_H
-#define _CORKSCREW_PTRACE_ARCH_H
-
-#include <corkscrew/ptrace.h>
-#include <corkscrew/map_info.h>
-#include <corkscrew/symbol_table.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Custom extra data we stuff into map_info_t structures as part
- * of our ptrace_context_t. */
-typedef struct {
-#ifdef __arm__
-    uintptr_t exidx_start;
-    size_t exidx_size;
-#elif __mips__
-    uintptr_t eh_frame_hdr;
-#elif __i386__
-    uintptr_t eh_frame_hdr;
-#endif
-    symbol_table_t* symbol_table;
-} map_info_data_t;
-
-void load_ptrace_map_info_data_arch(pid_t pid, map_info_t* mi, map_info_data_t* data);
-void free_ptrace_map_info_data_arch(map_info_t* mi, map_info_data_t* data);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _CORKSCREW_PTRACE_ARCH_H
diff --git a/libcorkscrew/ptrace.c b/libcorkscrew/ptrace.c
deleted file mode 100644
index be58f7f..0000000
--- a/libcorkscrew/ptrace.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.
- */
-
-#define LOG_TAG "Corkscrew"
-//#define LOG_NDEBUG 0
-
-#include "ptrace-arch.h"
-#include <corkscrew/ptrace.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/ptrace.h>
-#include <cutils/log.h>
-
-static const uint32_t ELF_MAGIC = 0x464C457f; // "ELF\0177"
-
-#ifndef PAGE_SIZE
-#define PAGE_SIZE 4096
-#endif
-
-#ifndef PAGE_MASK
-#define PAGE_MASK (~(PAGE_SIZE - 1))
-#endif
-
-void init_memory(memory_t* memory, const map_info_t* map_info_list) {
-    memory->tid = -1;
-    memory->map_info_list = map_info_list;
-}
-
-void init_memory_ptrace(memory_t* memory, pid_t tid) {
-    memory->tid = tid;
-    memory->map_info_list = NULL;
-}
-
-bool try_get_word(const memory_t* memory, uintptr_t ptr, uint32_t* out_value) {
-    ALOGV("try_get_word: reading word at %p", (void*) ptr);
-    if (ptr & 3) {
-        ALOGV("try_get_word: invalid pointer %p", (void*) ptr);
-        *out_value = 0xffffffffL;
-        return false;
-    }
-    if (memory->tid < 0) {
-        if (!is_readable_map(memory->map_info_list, ptr)) {
-            ALOGV("try_get_word: pointer %p not in a readable map", (void*) ptr);
-            *out_value = 0xffffffffL;
-            return false;
-        }
-        *out_value = *(uint32_t*)ptr;
-        return true;
-    } else {
-#if defined(__APPLE__)
-        ALOGV("no ptrace on Mac OS");
-        return false;
-#else
-        // ptrace() returns -1 and sets errno when the operation fails.
-        // To disambiguate -1 from a valid result, we clear errno beforehand.
-        errno = 0;
-        *out_value = ptrace(PTRACE_PEEKTEXT, memory->tid, (void*)ptr, NULL);
-        if (*out_value == 0xffffffffL && errno) {
-            ALOGV("try_get_word: invalid pointer 0x%08x reading from tid %d, "
-                    "ptrace() errno=%d", ptr, memory->tid, errno);
-            return false;
-        }
-        return true;
-#endif
-    }
-}
-
-bool try_get_word_ptrace(pid_t tid, uintptr_t ptr, uint32_t* out_value) {
-    memory_t memory;
-    init_memory_ptrace(&memory, tid);
-    return try_get_word(&memory, ptr, out_value);
-}
-
-static void load_ptrace_map_info_data(pid_t pid, map_info_t* mi) {
-    if (mi->is_executable && mi->is_readable) {
-        uint32_t elf_magic;
-        if (try_get_word_ptrace(pid, mi->start, &elf_magic) && elf_magic == ELF_MAGIC) {
-            map_info_data_t* data = (map_info_data_t*)calloc(1, sizeof(map_info_data_t));
-            if (data) {
-                mi->data = data;
-                if (mi->name[0]) {
-                    data->symbol_table = load_symbol_table(mi->name);
-                }
-#ifdef CORKSCREW_HAVE_ARCH
-                load_ptrace_map_info_data_arch(pid, mi, data);
-#endif
-            }
-        }
-    }
-}
-
-ptrace_context_t* load_ptrace_context(pid_t pid) {
-    ptrace_context_t* context =
-            (ptrace_context_t*)calloc(1, sizeof(ptrace_context_t));
-    if (context) {
-        context->map_info_list = load_map_info_list(pid);
-        for (map_info_t* mi = context->map_info_list; mi; mi = mi->next) {
-            load_ptrace_map_info_data(pid, mi);
-        }
-    }
-    return context;
-}
-
-static void free_ptrace_map_info_data(map_info_t* mi) {
-    map_info_data_t* data = (map_info_data_t*)mi->data;
-    if (data) {
-        if (data->symbol_table) {
-            free_symbol_table(data->symbol_table);
-        }
-#ifdef CORKSCREW_HAVE_ARCH
-        free_ptrace_map_info_data_arch(mi, data);
-#endif
-        free(data);
-        mi->data = NULL;
-    }
-}
-
-void free_ptrace_context(ptrace_context_t* context) {
-    for (map_info_t* mi = context->map_info_list; mi; mi = mi->next) {
-        free_ptrace_map_info_data(mi);
-    }
-    free_map_info_list(context->map_info_list);
-    free(context);
-}
-
-void find_symbol_ptrace(const ptrace_context_t* context,
-        uintptr_t addr, const map_info_t** out_map_info, const symbol_t** out_symbol) {
-    const map_info_t* mi = find_map_info(context->map_info_list, addr);
-    const symbol_t* symbol = NULL;
-    if (mi) {
-        const map_info_data_t* data = (const map_info_data_t*)mi->data;
-        if (data && data->symbol_table) {
-            symbol = find_symbol(data->symbol_table, addr - mi->start);
-        }
-    }
-    *out_map_info = mi;
-    *out_symbol = symbol;
-}
diff --git a/libcorkscrew/symbol_table.c b/libcorkscrew/symbol_table.c
deleted file mode 100644
index 982ccc8..0000000
--- a/libcorkscrew/symbol_table.c
+++ /dev/null
@@ -1,227 +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.
- */
-
-#define LOG_TAG "Corkscrew"
-//#define LOG_NDEBUG 0
-
-#include <corkscrew/symbol_table.h>
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <cutils/log.h>
-
-#if defined(__APPLE__)
-#else
-
-#include <elf.h>
-
-static bool is_elf(Elf32_Ehdr* e) {
-    return (e->e_ident[EI_MAG0] == ELFMAG0 &&
-            e->e_ident[EI_MAG1] == ELFMAG1 &&
-            e->e_ident[EI_MAG2] == ELFMAG2 &&
-            e->e_ident[EI_MAG3] == ELFMAG3);
-}
-
-#endif
-
-// Compare function for qsort
-static int qcompar(const void *a, const void *b) {
-    const symbol_t* asym = (const symbol_t*)a;
-    const symbol_t* bsym = (const symbol_t*)b;
-    if (asym->start > bsym->start) return 1;
-    if (asym->start < bsym->start) return -1;
-    return 0;
-}
-
-// Compare function for bsearch
-static int bcompar(const void *key, const void *element) {
-    uintptr_t addr = *(const uintptr_t*)key;
-    const symbol_t* symbol = (const symbol_t*)element;
-    if (addr < symbol->start) return -1;
-    if (addr >= symbol->end) return 1;
-    return 0;
-}
-
-symbol_table_t* load_symbol_table(const char *filename) {
-    symbol_table_t* table = NULL;
-#if !defined(__APPLE__)
-    ALOGV("Loading symbol table from '%s'.", filename);
-
-    int fd = open(filename, O_RDONLY);
-    if (fd < 0) {
-        goto out;
-    }
-
-    struct stat sb;
-    if (fstat(fd, &sb)) {
-        goto out_close;
-    }
-
-    size_t length = sb.st_size;
-    char* base = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
-    if (base == MAP_FAILED) {
-        goto out_close;
-    }
-
-    // Parse the file header
-    Elf32_Ehdr *hdr = (Elf32_Ehdr*)base;
-    if (!is_elf(hdr)) {
-        goto out_close;
-    }
-    Elf32_Shdr *shdr = (Elf32_Shdr*)(base + hdr->e_shoff);
-
-    // Search for the dynamic symbols section
-    int sym_idx = -1;
-    int dynsym_idx = -1;
-    for (Elf32_Half i = 0; i < hdr->e_shnum; i++) {
-        if (shdr[i].sh_type == SHT_SYMTAB) {
-            sym_idx = i;
-        }
-        if (shdr[i].sh_type == SHT_DYNSYM) {
-            dynsym_idx = i;
-        }
-    }
-    if (dynsym_idx == -1 && sym_idx == -1) {
-        goto out_unmap;
-    }
-
-    table = malloc(sizeof(symbol_table_t));
-    if(!table) {
-        goto out_unmap;
-    }
-    table->num_symbols = 0;
-
-    Elf32_Sym *dynsyms = NULL;
-    int dynnumsyms = 0;
-    char *dynstr = NULL;
-    if (dynsym_idx != -1) {
-        dynsyms = (Elf32_Sym*)(base + shdr[dynsym_idx].sh_offset);
-        dynnumsyms = shdr[dynsym_idx].sh_size / shdr[dynsym_idx].sh_entsize;
-        int dynstr_idx = shdr[dynsym_idx].sh_link;
-        dynstr = base + shdr[dynstr_idx].sh_offset;
-    }
-
-    Elf32_Sym *syms = NULL;
-    int numsyms = 0;
-    char *str = NULL;
-    if (sym_idx != -1) {
-        syms = (Elf32_Sym*)(base + shdr[sym_idx].sh_offset);
-        numsyms = shdr[sym_idx].sh_size / shdr[sym_idx].sh_entsize;
-        int str_idx = shdr[sym_idx].sh_link;
-        str = base + shdr[str_idx].sh_offset;
-    }
-
-    int dynsymbol_count = 0;
-    if (dynsym_idx != -1) {
-        // Iterate through the dynamic symbol table, and count how many symbols
-        // are actually defined
-        for (int i = 0; i < dynnumsyms; i++) {
-            if (dynsyms[i].st_shndx != SHN_UNDEF) {
-                dynsymbol_count++;
-            }
-        }
-    }
-
-    size_t symbol_count = 0;
-    if (sym_idx != -1) {
-        // Iterate through the symbol table, and count how many symbols
-        // are actually defined
-        for (int i = 0; i < numsyms; i++) {
-            if (syms[i].st_shndx != SHN_UNDEF
-                    && str[syms[i].st_name]
-                    && syms[i].st_value
-                    && syms[i].st_size) {
-                symbol_count++;
-            }
-        }
-    }
-
-    // Now, create an entry in our symbol table structure for each symbol...
-    table->num_symbols += symbol_count + dynsymbol_count;
-    table->symbols = malloc(table->num_symbols * sizeof(symbol_t));
-    if (!table->symbols) {
-        free(table);
-        table = NULL;
-        goto out_unmap;
-    }
-
-    size_t symbol_index = 0;
-    if (dynsym_idx != -1) {
-        // ...and populate them
-        for (int i = 0; i < dynnumsyms; i++) {
-            if (dynsyms[i].st_shndx != SHN_UNDEF) {
-                table->symbols[symbol_index].name = strdup(dynstr + dynsyms[i].st_name);
-                table->symbols[symbol_index].start = dynsyms[i].st_value;
-                table->symbols[symbol_index].end = dynsyms[i].st_value + dynsyms[i].st_size;
-                ALOGV("  [%d] '%s' 0x%08x-0x%08x (DYNAMIC)",
-                        symbol_index, table->symbols[symbol_index].name,
-                        table->symbols[symbol_index].start, table->symbols[symbol_index].end);
-                symbol_index += 1;
-            }
-        }
-    }
-
-    if (sym_idx != -1) {
-        // ...and populate them
-        for (int i = 0; i < numsyms; i++) {
-            if (syms[i].st_shndx != SHN_UNDEF
-                    && str[syms[i].st_name]
-                    && syms[i].st_value
-                    && syms[i].st_size) {
-                table->symbols[symbol_index].name = strdup(str + syms[i].st_name);
-                table->symbols[symbol_index].start = syms[i].st_value;
-                table->symbols[symbol_index].end = syms[i].st_value + syms[i].st_size;
-                ALOGV("  [%d] '%s' 0x%08x-0x%08x",
-                        symbol_index, table->symbols[symbol_index].name,
-                        table->symbols[symbol_index].start, table->symbols[symbol_index].end);
-                symbol_index += 1;
-            }
-        }
-    }
-
-    // Sort the symbol table entries, so they can be bsearched later
-    qsort(table->symbols, table->num_symbols, sizeof(symbol_t), qcompar);
-
-out_unmap:
-    munmap(base, length);
-
-out_close:
-    close(fd);
-#endif
-
-out:
-    return table;
-}
-
-void free_symbol_table(symbol_table_t* table) {
-    if (table) {
-        for (size_t i = 0; i < table->num_symbols; i++) {
-            free(table->symbols[i].name);
-        }
-        free(table->symbols);
-        free(table);
-    }
-}
-
-const symbol_t* find_symbol(const symbol_table_t* table, uintptr_t addr) {
-    if (!table) return NULL;
-    return (const symbol_t*)bsearch(&addr, table->symbols, table->num_symbols,
-            sizeof(symbol_t), bcompar);
-}
diff --git a/libcorkscrew/test.cpp b/libcorkscrew/test.cpp
deleted file mode 100644
index 22dfa7d..0000000
--- a/libcorkscrew/test.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include <corkscrew/backtrace.h>
-#include <corkscrew/symbol_table.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-int do_backtrace(float /* just to test demangling */) {
-  const size_t MAX_DEPTH = 32;
-  backtrace_frame_t* frames = (backtrace_frame_t*) malloc(sizeof(backtrace_frame_t) * MAX_DEPTH);
-  ssize_t frame_count = unwind_backtrace(frames, 0, MAX_DEPTH);
-  fprintf(stderr, "frame_count=%d\n", (int) frame_count);
-  if (frame_count <= 0) {
-    return frame_count;
-  }
-
-  backtrace_symbol_t* backtrace_symbols = (backtrace_symbol_t*) malloc(sizeof(backtrace_symbol_t) * frame_count);
-  get_backtrace_symbols(frames, frame_count, backtrace_symbols);
-
-  for (size_t i = 0; i < (size_t) frame_count; ++i) {
-    char line[MAX_BACKTRACE_LINE_LENGTH];
-    format_backtrace_line(i, &frames[i], &backtrace_symbols[i],
-                          line, MAX_BACKTRACE_LINE_LENGTH);
-    if (backtrace_symbols[i].symbol_name != NULL) {
-      // get_backtrace_symbols found the symbol's name with dladdr(3).
-      fprintf(stderr, "  %s\n", line);
-    } else {
-      // We don't have a symbol. Maybe this is a static symbol, and
-      // we can look it up?
-      symbol_table_t* symbols = NULL;
-      if (backtrace_symbols[i].map_name != NULL) {
-        symbols = load_symbol_table(backtrace_symbols[i].map_name);
-      }
-      const symbol_t* symbol = NULL;
-      if (symbols != NULL) {
-        symbol = find_symbol(symbols, frames[i].absolute_pc);
-      }
-      if (symbol != NULL) {
-        int offset = frames[i].absolute_pc - symbol->start;
-        fprintf(stderr, "  %s (%s%+d)\n", line, symbol->name, offset);
-      } else {
-        fprintf(stderr, "  %s (\?\?\?)\n", line);
-      }
-      free_symbol_table(symbols);
-    }
-  }
-
-  free_backtrace_symbols(backtrace_symbols, frame_count);
-  free(backtrace_symbols);
-  free(frames);
-  return frame_count;
-}
-
-struct C {
-  int g(int i);
-};
-
-__attribute__ ((noinline)) int C::g(int i) {
-  if (i == 0) {
-    return do_backtrace(0.1);
-  }
-  return g(i - 1);
-}
-
-extern "C" __attribute__ ((noinline)) int f() {
-  C c;
-  return c.g(5);
-}
-
-int main() {
-  flush_my_map_info_list();
-  f();
-
-  flush_my_map_info_list();
-  f();
-
-  return 0;
-}
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 635695a..20ad7ea 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -27,13 +27,6 @@
 	hashmap.c \
 	atomic.c.arm \
 	native_handle.c \
-	socket_inaddr_any_server.c \
-	socket_local_client.c \
-	socket_local_server.c \
-	socket_loopback_client.c \
-	socket_loopback_server.c \
-	socket_network_client.c \
-	sockets.c \
 	config_utils.c \
 	cpu_info.c \
 	load_file.c \
@@ -47,9 +40,6 @@
 	iosched_policy.c \
 	str_parms.c \
 
-commonHostSources := \
-        ashmem-host.c
-
 # some files must not be compiled when building against Mingw
 # they correspond to features not used by our host development tools
 # which are also hard or even impossible to port to native Win32
@@ -67,7 +57,18 @@
 ifneq ($(WINDOWS_HOST_ONLY),1)
     commonSources += \
         fs.c \
-        multiuser.c
+        multiuser.c \
+        socket_inaddr_any_server.c \
+        socket_local_client.c \
+        socket_local_server.c \
+        socket_loopback_client.c \
+        socket_loopback_server.c \
+        socket_network_client.c \
+        sockets.c \
+
+    commonHostSources += \
+        ashmem-host.c
+
 endif
 
 
@@ -75,9 +76,11 @@
 # ========================================================
 LOCAL_MODULE := libcutils
 LOCAL_SRC_FILES := $(commonSources) $(commonHostSources) dlmalloc_stubs.c
-LOCAL_LDLIBS := -lpthread
 LOCAL_STATIC_LIBRARIES := liblog
 LOCAL_CFLAGS += $(hostSmpFlag)
+ifneq ($(HOST_OS),windows)
+LOCAL_CFLAGS += -Werror
+endif
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 
@@ -86,9 +89,11 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := lib64cutils
 LOCAL_SRC_FILES := $(commonSources) $(commonHostSources) dlmalloc_stubs.c
-LOCAL_LDLIBS := -lpthread
 LOCAL_STATIC_LIBRARIES := lib64log
 LOCAL_CFLAGS += $(hostSmpFlag) -m64
+ifneq ($(HOST_OS),windows)
+LOCAL_CFLAGS += -Werror
+endif
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 # Tests for host
@@ -96,6 +101,9 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := tst_str_parms
 LOCAL_CFLAGS += -DTEST_STR_PARMS
+ifneq ($(HOST_OS),windows)
+LOCAL_CFLAGS += -Werror
+endif
 LOCAL_SRC_FILES := str_parms.c hashmap.c memory.c
 LOCAL_STATIC_LIBRARIES := liblog
 LOCAL_MODULE_TAGS := optional
@@ -135,7 +143,7 @@
 
 LOCAL_C_INCLUDES := $(libcutils_c_includes)
 LOCAL_STATIC_LIBRARIES := liblog
-LOCAL_CFLAGS += $(targetSmpFlag)
+LOCAL_CFLAGS += $(targetSmpFlag) -Werror
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -144,13 +152,13 @@
 # liblog symbols present in libcutils.
 LOCAL_WHOLE_STATIC_LIBRARIES := libcutils liblog
 LOCAL_SHARED_LIBRARIES := liblog
-LOCAL_CFLAGS += $(targetSmpFlag)
+LOCAL_CFLAGS += $(targetSmpFlag) -Werror
 LOCAL_C_INCLUDES := $(libcutils_c_includes)
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := tst_str_parms
-LOCAL_CFLAGS += -DTEST_STR_PARMS
+LOCAL_CFLAGS += -DTEST_STR_PARMS -Werror
 LOCAL_SRC_FILES := str_parms.c hashmap.c memory.c
 LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_MODULE_TAGS := optional
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/cache_wrapper.S b/libcutils/arch-x86/cache_wrapper.S
index 508fdd3..9eee25c 100644
--- a/libcutils/arch-x86/cache_wrapper.S
+++ b/libcutils/arch-x86/cache_wrapper.S
@@ -17,8 +17,15 @@
  * 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 */
+#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/ashmem-host.c b/libcutils/ashmem-host.c
index f03e130..4ac4f57 100644
--- a/libcutils/ashmem-host.c
+++ b/libcutils/ashmem-host.c
@@ -19,96 +19,102 @@
  * an ashmem-enabled kernel. See ashmem-dev.c for the real ashmem-based version.
  */
 
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
 #include <errno.h>
-#include <time.h>
+#include <fcntl.h>
 #include <limits.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
 
 #include <cutils/ashmem.h>
 
-int ashmem_create_region(const char *ignored, size_t size)
-{
-	static const char txt[] = "abcdefghijklmnopqrstuvwxyz"
-				  "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-	char name[64];
-	unsigned int retries = 0;
-	pid_t pid = getpid();
-	int fd;
+#ifndef __unused
+#define __unused __attribute__((__unused__))
+#endif
 
-	srand(time(NULL) + pid);
-
-retry:
-	/* not beautiful, its just wolf-like loop unrolling */
-	snprintf(name, sizeof(name), "/tmp/android-ashmem-%d-%c%c%c%c%c%c%c%c",
-		pid,
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
-		txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))]);
-
-	/* open O_EXCL & O_CREAT: we are either the sole owner or we fail */
-	fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
-	if (fd == -1) {
-		/* unlikely, but if we failed because `name' exists, retry */
-		if (errno == EEXIST && ++retries < 6)
-			goto retry;
-		return -1;
-	}
-
-	/* truncate the file to `len' bytes */
-	if (ftruncate(fd, size) == -1)
-		goto error;
-
-	if (unlink(name) == -1)
-		goto error;
-
-	return fd;
-error:
-	close(fd);
-	return -1;
+static pthread_once_t seed_initialized = PTHREAD_ONCE_INIT;
+static void initialize_random() {
+    srand(time(NULL) + getpid());
 }
 
-int ashmem_set_prot_region(int fd, int prot)
+int ashmem_create_region(const char *ignored __unused, size_t size)
 {
-	return 0;
+    static const char txt[] = "abcdefghijklmnopqrstuvwxyz"
+            "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    char name[64];
+    unsigned int retries = 0;
+    pid_t pid = getpid();
+    int fd;
+    if (pthread_once(&seed_initialized, &initialize_random) != 0) {
+        return -1;
+    }
+    do {
+        /* not beautiful, its just wolf-like loop unrolling */
+        snprintf(name, sizeof(name), "/tmp/android-ashmem-%d-%c%c%c%c%c%c%c%c",
+        pid,
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))],
+        txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))]);
+
+        /* open O_EXCL & O_CREAT: we are either the sole owner or we fail */
+        fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
+        if (fd == -1) {
+            /* unlikely, but if we failed because `name' exists, retry */
+            if (errno != EEXIST || ++retries >= 6) {
+                return -1;
+            }
+        }
+    } while (fd == -1);
+    /* truncate the file to `len' bytes */
+    if (ftruncate(fd, size) != -1 && unlink(name) != -1) {
+        return fd;
+    }
+    close(fd);
+    return -1;
 }
 
-int ashmem_pin_region(int fd, size_t offset, size_t len)
+int ashmem_set_prot_region(int fd __unused, int prot __unused)
 {
-	return ASHMEM_NOT_PURGED;
+    return 0;
 }
 
-int ashmem_unpin_region(int fd, size_t offset, size_t len)
+int ashmem_pin_region(int fd __unused, size_t offset __unused, size_t len __unused)
 {
-	return ASHMEM_IS_UNPINNED;
+    return ASHMEM_NOT_PURGED;
+}
+
+int ashmem_unpin_region(int fd __unused, size_t offset __unused, size_t len __unused)
+{
+    return ASHMEM_IS_UNPINNED;
 }
 
 int ashmem_get_size_region(int fd)
 {
-        struct stat buf;
-        int result;
+    struct stat buf;
+    int result;
 
-        result = fstat(fd, &buf);
-        if (result == -1) {
-                return -1;
-        }
+    result = fstat(fd, &buf);
+    if (result == -1) {
+        return -1;
+    }
 
-        // Check if this is an "ashmem" region.
-        // TODO: This is very hacky, and can easily break. We need some reliable indicator.
-        if (!(buf.st_nlink == 0 && S_ISREG(buf.st_mode))) {
-                errno = ENOTTY;
-                return -1;
-        }
+    // Check if this is an "ashmem" region.
+    // TODO: This is very hacky, and can easily break. We need some reliable indicator.
+    if (!(buf.st_nlink == 0 && S_ISREG(buf.st_mode))) {
+        errno = ENOTTY;
+        return -1;
+    }
 
-        return (int)buf.st_size;  // TODO: care about overflow (> 2GB file)?
+    return (int)buf.st_size;    // TODO: care about overflow (> 2GB file)?
 }
diff --git a/libcutils/cpu_info.c b/libcutils/cpu_info.c
index 23dda8a..21fa1dc 100644
--- a/libcutils/cpu_info.c
+++ b/libcutils/cpu_info.c
@@ -1,5 +1,4 @@
-/* libs/cutils/cpu_info.c
-**
+/*
 ** Copyright 2007, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
@@ -15,11 +14,12 @@
 ** limitations under the License.
 */
 
-#include <cutils/cpu_info.h>
-#include <stdlib.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
+#include <cutils/cpu_info.h>
+
 // we cache the serial number here.
 // this is also used as a fgets() line buffer when we are reading /proc/cpuinfo
 static char serial_number[100] = { 0 };
@@ -31,7 +31,6 @@
         FILE* file;
         char* chp, *end;
         char* whitespace;
-        int length;
         
         // read serial number from /proc/cpuinfo
         file = fopen("proc/cpuinfo", "r");
diff --git a/libcutils/debugger.c b/libcutils/debugger.c
index 7d907fc..056de5d 100644
--- a/libcutils/debugger.c
+++ b/libcutils/debugger.c
@@ -15,6 +15,7 @@
  */
 
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 #include <cutils/debugger.h>
@@ -28,9 +29,9 @@
     }
 
     debugger_msg_t msg;
+    memset(&msg, 0, sizeof(msg));
     msg.tid = tid;
     msg.action = DEBUGGER_ACTION_DUMP_TOMBSTONE;
-    msg.abort_msg_address = 0;
 
     int result = 0;
     if (TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg))) != sizeof(msg)) {
@@ -62,9 +63,9 @@
     }
 
     debugger_msg_t msg;
+    memset(&msg, 0, sizeof(msg));
     msg.tid = tid;
     msg.action = DEBUGGER_ACTION_DUMP_BACKTRACE;
-    msg.abort_msg_address = 0;
 
     int result = 0;
     if (TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg))) != sizeof(msg)) {
diff --git a/libcutils/dlmalloc_stubs.c b/libcutils/dlmalloc_stubs.c
index c327a55..2db473d 100644
--- a/libcutils/dlmalloc_stubs.c
+++ b/libcutils/dlmalloc_stubs.c
@@ -14,21 +14,22 @@
  * limitations under the License.
  */
 
-#include "../../../bionic/libc/bionic/dlmalloc.h"
-#include "cutils/log.h"
+#include "log/log.h"
+
+#define UNUSED __attribute__((__unused__))
 
 /*
  * Stubs for functions defined in bionic/libc/bionic/dlmalloc.c. These
  * are used in host builds, as the host libc will not contain these
  * functions.
  */
-void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*),
-                          void* arg)
+void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*) UNUSED,
+                          void* arg UNUSED)
 {
   ALOGW("Called host unimplemented stub: dlmalloc_inspect_all");
 }
 
-int dlmalloc_trim(size_t unused)
+int dlmalloc_trim(size_t unused UNUSED)
 {
   ALOGW("Called host unimplemented stub: dlmalloc_trim");
   return 0;
diff --git a/libcutils/iosched_policy.c b/libcutils/iosched_policy.c
index 5d90a01..67e101d 100644
--- a/libcutils/iosched_policy.c
+++ b/libcutils/iosched_policy.c
@@ -1,5 +1,4 @@
 /*
-**
 ** Copyright 2007-2014, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
@@ -15,12 +14,12 @@
 ** limitations under the License.
 */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
 #ifdef HAVE_SCHED_H
 
@@ -30,6 +29,9 @@
 /* #include <linux/ioprio.h> */
 extern int ioprio_set(int which, int who, int ioprio);
 extern int ioprio_get(int which, int who);
+#define __android_unused
+#else
+#define __android_unused __attribute__((__unused__))
 #endif
 
 enum {
@@ -41,7 +43,7 @@
 #define CLASS_SHIFT 13
 #define IOPRIO_NORM 4
 
-int android_set_ioprio(int pid, IoSchedClass clazz, int ioprio) {
+int android_set_ioprio(int pid __android_unused, IoSchedClass clazz __android_unused, int ioprio __android_unused) {
 #ifdef HAVE_ANDROID_OS
     if (ioprio_set(WHO_PROCESS, pid, ioprio | (clazz << CLASS_SHIFT))) {
         return -1;
@@ -50,7 +52,7 @@
     return 0;
 }
 
-int android_get_ioprio(int pid, IoSchedClass *clazz, int *ioprio) {
+int android_get_ioprio(int pid __android_unused, IoSchedClass *clazz, int *ioprio) {
 #ifdef HAVE_ANDROID_OS
     int rc;
 
diff --git a/libcutils/partition_utils.c b/libcutils/partition_utils.c
index 10539fa..823b162 100644
--- a/libcutils/partition_utils.c
+++ b/libcutils/partition_utils.c
@@ -14,12 +14,13 @@
  * limitations under the License.
  */
 
-#include <sys/types.h>
-#include <unistd.h>
 #include <fcntl.h>
-#include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/mount.h> /* for BLKGETSIZE */
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
 #include <cutils/properties.h>
 
 static int only_one_char(char *buf, int len, char c)
@@ -39,7 +40,7 @@
 int partition_wiped(char *source)
 {
     char buf[4096];
-    int fd, ret, wiped;
+    int fd, ret;
 
     if ((fd = open(source, O_RDONLY)) < 0) {
         return 0;
diff --git a/libcutils/process_name.c b/libcutils/process_name.c
index a6ab951..9c3dfb8 100644
--- a/libcutils/process_name.c
+++ b/libcutils/process_name.c
@@ -14,25 +14,27 @@
  * limitations under the License.
  */
 
+#include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
+#if defined(HAVE_PRCTL)
+#include <sys/prctl.h>
+#endif
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
 #include <cutils/process_name.h>
 #ifdef HAVE_ANDROID_OS
 #include <cutils/properties.h>
 #endif
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#if defined(HAVE_PRCTL)
-#include <sys/prctl.h>
-#endif
 
 #define PROCESS_NAME_DEVICE "/sys/qemu_trace/process_name"
 
 static const char* process_name = "unknown";
+#ifdef HAVE_ANDROID_OS
 static int running_in_emulator = -1;
+#endif
 
 void set_process_name(const char* new_name) {
 #ifdef HAVE_ANDROID_OS
diff --git a/libcutils/qtaguid.c b/libcutils/qtaguid.c
index 899a7b4..00e211c 100644
--- a/libcutils/qtaguid.c
+++ b/libcutils/qtaguid.c
@@ -1,5 +1,4 @@
-/* libcutils/qtaguid.c
-**
+/*
 ** Copyright 2011, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
@@ -146,7 +145,7 @@
 
 int qtaguid_deleteTagData(int tag, uid_t uid) {
     char lineBuf[CTRL_MAX_INPUT_LEN];
-    int fd, cnt = 0, res = 0;
+    int cnt = 0, res = 0;
     uint64_t kTag = (uint64_t)tag << 32;
 
     ALOGV("Deleting tag data with tag %" PRIx64 "{%d,0} for uid %d", kTag, tag, uid);
@@ -164,8 +163,6 @@
 }
 
 int qtaguid_setPacifier(int on) {
-    int param_fd;
-    int res;
     const char *value;
 
     value = on ? "Y" : "N";
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index d20d217..9f092d6 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -1,6 +1,4 @@
-
-/* libs/cutils/sched_policy.c
-**
+/*
 ** Copyright 2007, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
@@ -18,14 +16,17 @@
 
 #define LOG_TAG "SchedPolicy"
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
 #include <cutils/sched_policy.h>
-#include <cutils/log.h>
+#include <log/log.h>
+
+#define UNUSED __attribute__((__unused__))
 
 /* Re-map SP_DEFAULT to the system default policy, and leave other values unchanged.
  * Call this any place a SchedPolicy is used as an input parameter.
@@ -331,12 +332,12 @@
 
 /* Stubs for non-Android targets. */
 
-int set_sched_policy(int tid, SchedPolicy policy)
+int set_sched_policy(int tid UNUSED, SchedPolicy policy UNUSED)
 {
     return 0;
 }
 
-int get_sched_policy(int tid, SchedPolicy *policy)
+int get_sched_policy(int tid UNUSED, SchedPolicy *policy)
 {
     *policy = SP_SYSTEM_DEFAULT;
     return 0;
diff --git a/libcutils/socket_inaddr_any_server.c b/libcutils/socket_inaddr_any_server.c
index 7d5dab4..6c849de 100644
--- a/libcutils/socket_inaddr_any_server.c
+++ b/libcutils/socket_inaddr_any_server.c
@@ -1,5 +1,4 @@
-/* libs/cutils/socket_inaddr_any_server.c
-**
+/*
 ** Copyright 2006, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
@@ -15,13 +14,11 @@
 ** limitations under the License.
 */
 
-#include <cutils/sockets.h>
-
+#include <errno.h>
+#include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <errno.h>
-#include <stddef.h>
 
 #ifndef HAVE_WINSOCK
 #include <sys/socket.h>
@@ -30,13 +27,14 @@
 #include <netinet/in.h>
 #endif
 
+#include <cutils/sockets.h>
+
 #define LISTEN_BACKLOG 4
 
 /* open listen() port on any interface */
 int socket_inaddr_any_server(int port, int type)
 {
     struct sockaddr_in addr;
-    size_t alen;
     int s, n;
 
     memset(&addr, 0, sizeof(addr));
@@ -48,7 +46,7 @@
     if(s < 0) return -1;
 
     n = 1;
-    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof(n));
 
     if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
         close(s);
diff --git a/libcutils/socket_local_client.c b/libcutils/socket_local_client.c
index 5310516..ddcc2da 100644
--- a/libcutils/socket_local_client.c
+++ b/libcutils/socket_local_client.c
@@ -14,13 +14,13 @@
  * limitations under the License.
  */
 
-#include <cutils/sockets.h>
-
+#include <errno.h>
+#include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <errno.h>
-#include <stddef.h>
+
+#include <cutils/sockets.h>
 
 #ifdef HAVE_WINSOCK
 
@@ -128,7 +128,6 @@
 {
     struct sockaddr_un addr;
     socklen_t alen;
-    size_t namelen;
     int err;
 
     err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);
diff --git a/libcutils/socket_loopback_client.c b/libcutils/socket_loopback_client.c
index cb82c5e..9aed7b7 100644
--- a/libcutils/socket_loopback_client.c
+++ b/libcutils/socket_loopback_client.c
@@ -1,5 +1,4 @@
-/* libs/cutils/socket_loopback_client.c
-**
+/*
 ** Copyright 2006, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
@@ -15,13 +14,11 @@
 ** limitations under the License.
 */
 
-#include <cutils/sockets.h>
-
+#include <errno.h>
+#include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <errno.h>
-#include <stddef.h>
 
 #ifndef HAVE_WINSOCK
 #include <sys/socket.h>
@@ -30,6 +27,8 @@
 #include <netinet/in.h>
 #endif
 
+#include <cutils/sockets.h>
+
 /* Connect to port on the loopback IP interface. type is
  * SOCK_STREAM or SOCK_DGRAM. 
  * return is a file descriptor or -1 on error
@@ -37,7 +36,6 @@
 int socket_loopback_client(int port, int type)
 {
     struct sockaddr_in addr;
-    socklen_t alen;
     int s;
 
     memset(&addr, 0, sizeof(addr));
diff --git a/libcutils/socket_loopback_server.c b/libcutils/socket_loopback_server.c
index 3208488..71afce7 100644
--- a/libcutils/socket_loopback_server.c
+++ b/libcutils/socket_loopback_server.c
@@ -1,5 +1,4 @@
-/* libs/cutils/socket_loopback_server.c
-**
+/*
 ** Copyright 2006, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
@@ -15,13 +14,11 @@
 ** limitations under the License.
 */
 
-#include <cutils/sockets.h>
-
+#include <errno.h>
+#include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <errno.h>
-#include <stddef.h>
 
 #define LISTEN_BACKLOG 4
 
@@ -32,11 +29,12 @@
 #include <netinet/in.h>
 #endif
 
+#include <cutils/sockets.h>
+
 /* open listen() port on loopback interface */
 int socket_loopback_server(int port, int type)
 {
     struct sockaddr_in addr;
-    size_t alen;
     int s, n;
 
     memset(&addr, 0, sizeof(addr));
@@ -48,7 +46,7 @@
     if(s < 0) return -1;
 
     n = 1;
-    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof(n));
 
     if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
         close(s);
diff --git a/libcutils/socket_network_client.c b/libcutils/socket_network_client.c
index a64006c..4826033 100644
--- a/libcutils/socket_network_client.c
+++ b/libcutils/socket_network_client.c
@@ -1,5 +1,4 @@
-/* libs/cutils/socket_network_client.c
-**
+/*
 ** Copyright 2006, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
@@ -15,22 +14,20 @@
 ** limitations under the License.
 */
 
-#include <cutils/sockets.h>
-
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <errno.h>
-#include <stddef.h>
 
-#ifndef HAVE_WINSOCK
 #include <sys/socket.h>
 #include <sys/select.h>
 #include <sys/types.h>
 #include <netinet/in.h>
 #include <netdb.h>
-#endif
 
+#include <cutils/sockets.h>
 
 /* Connect to port on the IP interface. type is
  * SOCK_STREAM or SOCK_DGRAM. 
@@ -38,28 +35,92 @@
  */
 int socket_network_client(const char *host, int port, int type)
 {
+    return socket_network_client_timeout(host, port, type, 0);
+}
+
+/* Connect to port on the IP interface. type is SOCK_STREAM or SOCK_DGRAM.
+ * timeout in seconds return is a file descriptor or -1 on error
+ */
+int socket_network_client_timeout(const char *host, int port, int type, int timeout)
+{
     struct hostent *hp;
     struct sockaddr_in addr;
     socklen_t alen;
     int s;
+    int flags = 0, error = 0, ret = 0;
+    fd_set rset, wset;
+    socklen_t len = sizeof(error);
+    struct timeval ts;
+
+    ts.tv_sec = timeout;
+    ts.tv_usec = 0;
 
     hp = gethostbyname(host);
-    if(hp == 0) return -1;
-    
+    if (hp == 0) return -1;
+
     memset(&addr, 0, sizeof(addr));
     addr.sin_family = hp->h_addrtype;
     addr.sin_port = htons(port);
     memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
 
     s = socket(hp->h_addrtype, type, 0);
-    if(s < 0) return -1;
+    if (s < 0) return -1;
 
-    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+    if ((flags = fcntl(s, F_GETFL, 0)) < 0) {
+        close(s);
+        return -1;
+    }
+
+    if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
+        close(s);
+        return -1;
+    }
+
+    if ((ret = connect(s, (struct sockaddr *) &addr, sizeof(addr))) < 0) {
+        if (errno != EINPROGRESS) {
+            close(s);
+            return -1;
+        }
+    }
+
+    if (ret == 0)
+        goto done;
+
+    FD_ZERO(&rset);
+    FD_SET(s, &rset);
+    wset = rset;
+
+    if ((ret = select(s + 1, &rset, &wset, NULL, (timeout) ? &ts : NULL)) < 0) {
+        close(s);
+        return -1;
+    }
+    if (ret == 0) {   // we had a timeout
+        errno = ETIMEDOUT;
+        close(s);
+        return -1;
+    }
+
+    if (FD_ISSET(s, &rset) || FD_ISSET(s, &wset)) {
+        if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
+            close(s);
+            return -1;
+        }
+    } else {
+        close(s);
+        return -1;
+    }
+
+    if (error) {  // check if we had a socket error
+        errno = error;
+        close(s);
+        return -1;
+    }
+
+done:
+    if (fcntl(s, F_SETFL, flags) < 0) {
         close(s);
         return -1;
     }
 
     return s;
-
 }
-
diff --git a/libcutils/sockets.c b/libcutils/sockets.c
index b5a1b3d..15ede2b 100644
--- a/libcutils/sockets.c
+++ b/libcutils/sockets.c
@@ -14,15 +14,18 @@
  * limitations under the License.
  */
 
-#include <cutils/log.h>
 #include <cutils/sockets.h>
+#include <log/log.h>
 
 #ifdef HAVE_ANDROID_OS
 /* For the socket trust (credentials) check */
 #include <private/android_filesystem_config.h>
+#define __android_unused
+#else
+#define __android_unused __attribute__((__unused__))
 #endif
 
-bool socket_peer_is_trusted(int fd)
+bool socket_peer_is_trusted(int fd __android_unused)
 {
 #ifdef HAVE_ANDROID_OS
     struct ucred cr;
diff --git a/libcutils/str_parms.c b/libcutils/str_parms.c
index 953b91d..2e3ce9f 100644
--- a/libcutils/str_parms.c
+++ b/libcutils/str_parms.c
@@ -25,10 +25,9 @@
 #include <string.h>
 
 #include <cutils/hashmap.h>
-#include <cutils/log.h>
 #include <cutils/memory.h>
-
 #include <cutils/str_parms.h>
+#include <log/log.h>
 
 #define UNUSED __attribute__((unused))
 
@@ -374,8 +373,6 @@
 
 int main(void)
 {
-    struct str_parms *str_parms;
-
     test_str_parms_str("");
     test_str_parms_str(";");
     test_str_parms_str("=");
diff --git a/libcutils/threads.c b/libcutils/threads.c
index 42cc928..bf182f0 100644
--- a/libcutils/threads.c
+++ b/libcutils/threads.c
@@ -1,5 +1,4 @@
-/* libs/cutils/threads.c
-**
+/*
 ** Copyright (C) 2007, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
@@ -14,13 +13,12 @@
 ** See the License for the specific language governing permissions and 
 ** limitations under the License.
 */
+
 #include <cutils/threads.h>
 
 #ifdef HAVE_PTHREADS
 void*  thread_store_get( thread_store_t*  store )
 {
-    const pthread_key_t  k = store->tls;
-
     if (!store->has_tls)
         return NULL;
 
diff --git a/libcutils/trace.c b/libcutils/trace.c
index 9754a44..f57aac2 100644
--- a/libcutils/trace.c
+++ b/libcutils/trace.c
@@ -28,7 +28,7 @@
 #include <cutils/trace.h>
 
 #define LOG_TAG "cutils-trace"
-#include <cutils/log.h>
+#include <log/log.h>
 
 volatile int32_t        atrace_is_ready      = 0;
 int                     atrace_marker_fd     = -1;
@@ -86,7 +86,6 @@
 static bool atrace_is_app_tracing_enabled()
 {
     bool sys_debuggable = false;
-    bool proc_debuggable = false;
     char value[PROPERTY_VALUE_MAX];
     bool result = false;
 
diff --git a/libdiskconfig/Android.mk b/libdiskconfig/Android.mk
index b5d83fa..624e385 100644
--- a/libdiskconfig/Android.mk
+++ b/libdiskconfig/Android.mk
@@ -12,6 +12,7 @@
 LOCAL_MODULE := libdiskconfig
 LOCAL_MODULE_TAGS := optional
 LOCAL_SYSTEM_SHARED_LIBRARIES := libcutils liblog libc
+LOCAL_CFLAGS := -Werror
 include $(BUILD_SHARED_LIBRARY)
 
 ifeq ($(HOST_OS),linux)
diff --git a/libdiskconfig/diskutils.c b/libdiskconfig/diskutils.c
index 7659632..5d0ee62 100644
--- a/libdiskconfig/diskutils.c
+++ b/libdiskconfig/diskutils.c
@@ -41,7 +41,7 @@
     int done = 0;
     uint64_t total = 0;
 
-    ALOGI("Writing RAW image '%s' to '%s' (offset=%llu)", src, dst, offset);
+    ALOGI("Writing RAW image '%s' to '%s' (offset=%llu)", src, dst, (unsigned long long)offset);
     if ((src_fd = open(src, O_RDONLY)) < 0) {
         ALOGE("Could not open %s for reading (errno=%d).", src, errno);
         goto fail;
@@ -54,7 +54,7 @@
         }
 
         if (lseek64(dst_fd, offset, SEEK_SET) != offset) {
-            ALOGE("Could not seek to offset %lld in %s.", offset, dst);
+            ALOGE("Could not seek to offset %lld in %s.", (long long)offset, dst);
             goto fail;
         }
     }
@@ -102,7 +102,7 @@
     if (dst_fd >= 0)
         fsync(dst_fd);
 
-    ALOGI("Wrote %" PRIu64 " bytes to %s @ %lld", total, dst, offset);
+    ALOGI("Wrote %" PRIu64 " bytes to %s @ %lld", total, dst, (long long)offset);
 
     close(src_fd);
     if (dst_fd >= 0)
diff --git a/libdiskconfig/write_lst.c b/libdiskconfig/write_lst.c
index 826ef7a..90b1c82 100644
--- a/libdiskconfig/write_lst.c
+++ b/libdiskconfig/write_lst.c
@@ -71,18 +71,18 @@
 {
     for(; lst; lst = lst->next) {
         if (lseek64(fd, lst->offset, SEEK_SET) != (loff_t)lst->offset) {
-            ALOGE("Cannot seek to the specified position (%lld).", lst->offset);
+            ALOGE("Cannot seek to the specified position (%lld).", (long long)lst->offset);
             goto fail;
         }
 
         if (!test) {
             if (write(fd, lst->data, lst->len) != (int)lst->len) {
                 ALOGE("Failed writing %u bytes at position %lld.", lst->len,
-                     lst->offset);
+                     (long long)lst->offset);
                 goto fail;
             }
         } else
-            ALOGI("Would write %d bytes @ offset %lld.", lst->len, lst->offset);
+            ALOGI("Would write %d bytes @ offset %lld.", lst->len, (long long)lst->offset);
     }
 
     return 0;
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 5e01903..69ca416 100644
--- a/liblog/Android.mk
+++ b/liblog/Android.mk
@@ -57,11 +57,7 @@
 # ========================================================
 LOCAL_MODULE := liblog
 LOCAL_SRC_FILES := $(liblog_host_sources)
-LOCAL_LDLIBS := -lpthread
-ifeq ($(strip $(HOST_OS)),linux)
-LOCAL_LDLIBS += -lrt
-endif
-LOCAL_CFLAGS := -DFAKE_LOG_DEVICE=1
+LOCAL_CFLAGS := -DFAKE_LOG_DEVICE=1 -Werror
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -78,11 +74,7 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := lib64log
 LOCAL_SRC_FILES := $(liblog_host_sources)
-LOCAL_LDLIBS := -lpthread
-ifeq ($(strip $(HOST_OS)),linux)
-LOCAL_LDLIBS += -lrt
-endif
-LOCAL_CFLAGS := -DFAKE_LOG_DEVICE=1 -m64
+LOCAL_CFLAGS := -DFAKE_LOG_DEVICE=1 -m64 -Werror
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 # Shared and static library for target
@@ -90,13 +82,13 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := liblog
 LOCAL_SRC_FILES := $(liblog_target_sources)
-LOCAL_CFLAGS := $(liblog_cflags)
+LOCAL_CFLAGS := -Werror
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := liblog
 LOCAL_WHOLE_STATIC_LIBRARIES := liblog
-LOCAL_CFLAGS := $(liblog_cflags)
+LOCAL_CFLAGS := -Werror
 include $(BUILD_SHARED_LIBRARY)
 
 include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/liblog/event_tag_map.c b/liblog/event_tag_map.c
index f3d1e2f..bea99aa 100644
--- a/liblog/event_tag_map.c
+++ b/liblog/event_tag_map.c
@@ -13,15 +13,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include <log/event_tag_map.h>
-#include <log/log.h>
 
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
-#include <fcntl.h>
 #include <sys/mman.h>
-#include <errno.h>
-#include <assert.h>
+
+#include <log/event_tag_map.h>
+#include <log/log.h>
 
 #define OUT_TAG "EventTagMap"
 
@@ -52,7 +53,6 @@
 static int parseMapLines(EventTagMap* map);
 static int scanTagLine(char** pData, EventTag* tag, int lineNum);
 static int sortTags(EventTagMap* map);
-static void dumpTags(const EventTagMap* map);
 
 
 /*
@@ -185,8 +185,6 @@
  */
 static int processFile(EventTagMap* map)
 {
-    EventTag* tagArray = NULL;
-
     /* get a tag count */
     map->numTags = countMapLines(map);
     if (map->numTags < 0)
@@ -422,17 +420,3 @@
 
     return 0;
 }
-
-/*
- * Dump the tag array for debugging.
- */
-static void dumpTags(const EventTagMap* map)
-{
-    int i;
-
-    for (i = 0; i < map->numTags; i++) {
-        const EventTag* tag = &map->tagArray[i];
-        printf("  %3d: %6d '%s'\n", i, tag->tagIndex, tag->tagStr);
-    }
-}
-
diff --git a/liblog/fake_log_device.c b/liblog/fake_log_device.c
index da83a85..136792d 100644
--- a/liblog/fake_log_device.c
+++ b/liblog/fake_log_device.c
@@ -21,18 +21,22 @@
  */
 #include "fake_log_device.h"
 
-#include <log/logd.h>
-
-#include <stdlib.h>
-#include <string.h>
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <log/logd.h>
 
 #ifdef HAVE_PTHREADS
 #include <pthread.h>
 #endif
 
+#ifndef __unused
+#define __unused __attribute__((__unused__))
+#endif
+
 #define kMaxTagLen  16      /* from the long-dead utils/Log.cpp */
 
 #define kTagSetSize 16      /* arbitrary */
@@ -613,7 +617,7 @@
 /*
  * Open a log output device and return a fake fd.
  */
-static int logOpen(const char* pathName, int flags)
+static int logOpen(const char* pathName, int flags __unused)
 {
     LogState *logState;
     int fd = -1;
diff --git a/liblog/log_read.c b/liblog/log_read.c
index 11fe848..ca5a1a7 100644
--- a/liblog/log_read.c
+++ b/liblog/log_read.c
@@ -23,6 +23,7 @@
 #define NOMINMAX /* for windows to suppress definition of min in stdlib.h */
 #include <stdlib.h>
 #include <string.h>
+#include <sys/cdefs.h>
 #include <unistd.h>
 
 #include <cutils/list.h>
@@ -34,7 +35,9 @@
 #define min(x,y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))
 
 #define WEAK __attribute__((weak))
-#define UNUSED __attribute__((unused))
+#ifndef __unused
+#define __unused __attribute__((unused))
+#endif
 
 /* Private copy of ../libcutils/socket_local_client.c prevent library loops */
 
@@ -142,11 +145,10 @@
  * Used by AndroidSocketImpl
  */
 int WEAK socket_local_client_connect(int fd, const char *name, int namespaceId,
-                                     int type UNUSED)
+                                     int type __unused)
 {
     struct sockaddr_un addr;
     socklen_t alen;
-    size_t namelen;
     int err;
 
     err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);
@@ -409,7 +411,7 @@
 /*
  * returns the logger version
  */
-int android_logger_get_log_version(struct logger *logger UNUSED)
+int android_logger_get_log_version(struct logger *logger __unused)
 {
     return 3;
 }
@@ -420,7 +422,6 @@
 ssize_t android_logger_get_statistics(struct logger_list *logger_list,
                                       char *buf, size_t len)
 {
-    struct listnode *node;
     struct logger *logger;
     char *cp = buf;
     size_t remaining = len;
@@ -440,13 +441,13 @@
     return send_log_msg(NULL, NULL, buf, len);
 }
 
-ssize_t android_logger_get_prune_list(struct logger_list *logger_list UNUSED,
+ssize_t android_logger_get_prune_list(struct logger_list *logger_list __unused,
                                       char *buf, size_t len)
 {
     return send_log_msg(NULL, "getPruneList", buf, len);
 }
 
-int android_logger_set_prune_list(struct logger_list *logger_list UNUSED,
+int android_logger_set_prune_list(struct logger_list *logger_list __unused,
                                   char *buf, size_t len)
 {
     const char cmd[] = "setPruneList ";
@@ -512,9 +513,7 @@
 struct logger *android_logger_open(struct logger_list *logger_list,
                                    log_id_t id)
 {
-    struct listnode *node;
     struct logger *logger;
-    char *n;
 
     if (!logger_list || (id >= LOG_ID_MAX)) {
         goto err;
@@ -561,7 +560,7 @@
     return logger_list;
 }
 
-static void caught_signal(int signum UNUSED)
+static void caught_signal(int signum __unused)
 {
 }
 
diff --git a/liblog/log_read_kern.c b/liblog/log_read_kern.c
index 021fe47..41b8a51 100644
--- a/liblog/log_read_kern.c
+++ b/liblog/log_read_kern.c
@@ -21,12 +21,13 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/cdefs.h>
+#include <sys/ioctl.h>
+
 #include <cutils/list.h>
 #include <log/log.h>
 #include <log/logger.h>
 
-#include <sys/ioctl.h>
-
 #define __LOGGERIO     0xAE
 
 #define LOGGER_GET_LOG_BUF_SIZE    _IO(__LOGGERIO, 1) /* size of log */
@@ -51,7 +52,9 @@
          logger != node_to_item(&(logger_list)->node, struct logger, node); \
          logger = node_to_item((logger)->node.next, struct logger, node))
 
-#define UNUSED __attribute__((unused))
+#ifndef __unused
+#define __unused __attribute__((unused))
+#endif
 
 /* In the future, we would like to make this list extensible */
 static const char *LOG_NAME[LOG_ID_MAX] = {
@@ -233,8 +236,8 @@
     return logger_ioctl(logger, LOGGER_GET_LOG_BUF_SIZE, O_RDWR);
 }
 
-int android_logger_set_log_size(struct logger *logger UNUSED,
-                                unsigned long size UNUSED)
+int android_logger_set_log_size(struct logger *logger __unused,
+                                unsigned long size __unused)
 {
     return -ENOTSUP;
 }
@@ -262,21 +265,21 @@
  */
 static const char unsupported[] = "18\nNot Supported\n\f";
 
-ssize_t android_logger_get_statistics(struct logger_list *logger_list UNUSED,
+ssize_t android_logger_get_statistics(struct logger_list *logger_list __unused,
                                       char *buf, size_t len)
 {
     strncpy(buf, unsupported, len);
     return -ENOTSUP;
 }
 
-ssize_t android_logger_get_prune_list(struct logger_list *logger_list UNUSED,
+ssize_t android_logger_get_prune_list(struct logger_list *logger_list __unused,
                                       char *buf, size_t len)
 {
     strncpy(buf, unsupported, len);
     return -ENOTSUP;
 }
 
-int android_logger_set_prune_list(struct logger_list *logger_list UNUSED,
+int android_logger_set_prune_list(struct logger_list *logger_list __unused,
                                   char *buf, size_t len)
 {
     static const char unsupported_error[] = "Unsupported";
@@ -302,7 +305,7 @@
 }
 
 struct logger_list *android_logger_list_alloc_time(int mode,
-                                                   log_time start UNUSED,
+                                                   log_time start __unused,
                                                    pid_t pid)
 {
     return android_logger_list_alloc(mode, 0, pid);
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index bd36a65..f10eb8e 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -49,12 +49,15 @@
 static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
 #endif
 
-#define UNUSED  __attribute__((__unused__))
+#ifndef __unused
+#define __unused  __attribute__((__unused__))
+#endif
 
-static int logd_fd = -1;
 #if FAKE_LOG_DEVICE
 #define WEAK __attribute__((weak))
 static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1, -1 };
+#else
+static int logd_fd = -1;
 #endif
 
 /*
@@ -77,12 +80,14 @@
     return (g_log_status == kLogAvailable);
 }
 
+#if !FAKE_LOG_DEVICE
 /* give up, resources too limited */
-static int __write_to_log_null(log_id_t log_fd UNUSED, struct iovec *vec UNUSED,
-                               size_t nr UNUSED)
+static int __write_to_log_null(log_id_t log_fd __unused, struct iovec *vec __unused,
+                               size_t nr __unused)
 {
     return -1;
 }
+#endif
 
 /* log_init_lock assumed */
 static int __write_to_log_initialize()
@@ -154,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.
          */
@@ -188,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();
 
@@ -195,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);
 
@@ -323,6 +331,13 @@
             tag = tmp_tag;
     }
 
+#if __BIONIC__
+    if (prio == ANDROID_LOG_FATAL) {
+        extern void __android_set_abort_message(const char*);
+        __android_set_abort_message(msg);
+    }
+#endif
+
     vec[0].iov_base   = (unsigned char *) &prio;
     vec[0].iov_len    = 1;
     vec[1].iov_base   = (void *) tag;
@@ -422,14 +437,8 @@
             strcpy(buf, "Unspecified assertion failed");
     }
 
-#if __BIONIC__
-    // Ensure debuggerd gets to see what went wrong by keeping the C library in the loop.
-    extern __noreturn void __android_fatal(const char* tag, const char* format, ...) __printflike(2, 3);
-    __android_fatal(tag ? tag : "", "%s", buf);
-#else
     __android_log_write(ANDROID_LOG_FATAL, tag, buf);
     __builtin_trap(); /* trap so we have a chance to debug the situation */
-#endif
     /* NOTREACHED */
 }
 
diff --git a/liblog/logd_write_kern.c b/liblog/logd_write_kern.c
index 8c707ad..1d10748 100644
--- a/liblog/logd_write_kern.c
+++ b/liblog/logd_write_kern.c
@@ -57,7 +57,9 @@
 static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
 #endif
 
-#define UNUSED  __attribute__((__unused__))
+#ifndef __unused
+#define __unused  __attribute__((__unused__))
+#endif
 
 static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1 };
 
@@ -81,8 +83,8 @@
     return (g_log_status == kLogAvailable);
 }
 
-static int __write_to_log_null(log_id_t log_fd UNUSED, struct iovec *vec UNUSED,
-                               size_t nr UNUSED)
+static int __write_to_log_null(log_id_t log_fd __unused, struct iovec *vec __unused,
+                               size_t nr __unused)
 {
     return -1;
 }
@@ -173,6 +175,13 @@
             tag = tmp_tag;
     }
 
+#if __BIONIC__
+    if (prio == ANDROID_LOG_FATAL) {
+        extern void __android_set_abort_message(const char*);
+        __android_set_abort_message(msg);
+    }
+#endif
+
     vec[0].iov_base   = (unsigned char *) &prio;
     vec[0].iov_len    = 1;
     vec[1].iov_base   = (void *) tag;
@@ -272,14 +281,8 @@
             strcpy(buf, "Unspecified assertion failed");
     }
 
-#if __BIONIC__
-    // Ensure debuggerd gets to see what went wrong by keeping the C library in the loop.
-    extern __noreturn void __android_fatal(const char* tag, const char* format, ...) __printflike(2, 3);
-    __android_fatal(tag ? tag : "", "%s", buf);
-#else
     __android_log_write(ANDROID_LOG_FATAL, tag, buf);
     __builtin_trap(); /* trap so we have a chance to debug the situation */
-#endif
     /* NOTREACHED */
 }
 
diff --git a/liblog/logprint.c b/liblog/logprint.c
index a7480d5..08e830a 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -17,14 +17,14 @@
 
 #define _GNU_SOURCE /* for asprintf */
 
-#include <ctype.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <assert.h>
 #include <arpa/inet.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include <log/logd.h>
 #include <log/logprint.h>
@@ -52,15 +52,7 @@
     return p_ret;
 }
 
-static void filterinfo_free(FilterInfo *p_info)
-{
-    if (p_info == NULL) {
-        return;
-    }
-
-    free(p_info->mTag);
-    p_info->mTag = NULL;
-}
+/* balance to above, filterinfo_free left unimplemented */
 
 /*
  * Note: also accepts 0-9 priorities
@@ -139,23 +131,6 @@
     return p_format->global_pri;
 }
 
-/** for debugging */
-static void dumpFilters(AndroidLogFormat *p_format)
-{
-    FilterInfo *p_fi;
-
-    for (p_fi = p_format->filters ; p_fi != NULL ; p_fi = p_fi->p_next) {
-        char cPri = filterPriToChar(p_fi->mPri);
-        if (p_fi->mPri == ANDROID_LOG_DEFAULT) {
-            cPri = filterPriToChar(p_format->global_pri);
-        }
-        fprintf(stderr,"%s:%c\n", p_fi->mTag, cPri);
-    }
-
-    fprintf(stderr,"*:%c\n", filterPriToChar(p_format->global_pri));
-
-}
-
 /**
  * returns 1 if this log line should be printed based on its priority
  * and tag, and 0 if it should not
@@ -234,7 +209,6 @@
 int android_log_addFilterRule(AndroidLogFormat *p_format,
         const char *filterExpression)
 {
-    size_t i=0;
     size_t tagNameLength;
     android_LogPriority pri = ANDROID_LOG_DEFAULT;
 
@@ -718,7 +692,6 @@
 #endif
     struct tm* ptm;
     char timeBuf[32];
-    char headerBuf[128];
     char prefixBuf[128], suffixBuf[128];
     char priChar;
     int prefixSuffixIsHeaderFooter = 0;
@@ -817,7 +790,6 @@
     /* the following code is tragically unreadable */
 
     size_t numLines;
-    size_t i;
     char *p;
     size_t bufferSize;
     const char *pm;
@@ -938,88 +910,3 @@
 
     return ret;
 }
-
-
-
-void logprint_run_tests()
-{
-#if 0
-
-    fprintf(stderr, "tests disabled\n");
-
-#else
-
-    int err;
-    const char *tag;
-    AndroidLogFormat *p_format;
-
-    p_format = android_log_format_new();
-
-    fprintf(stderr, "running tests\n");
-
-    tag = "random";
-
-    android_log_addFilterRule(p_format,"*:i");
-
-    assert (ANDROID_LOG_INFO == filterPriForTag(p_format, "random"));
-    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
-    android_log_addFilterRule(p_format, "*");
-    assert (ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random"));
-    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
-    android_log_addFilterRule(p_format, "*:v");
-    assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random"));
-    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
-    android_log_addFilterRule(p_format, "*:i");
-    assert (ANDROID_LOG_INFO == filterPriForTag(p_format, "random"));
-    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
-
-    android_log_addFilterRule(p_format, "random");
-    assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random"));
-    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
-    android_log_addFilterRule(p_format, "random:v");
-    assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random"));
-    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
-    android_log_addFilterRule(p_format, "random:d");
-    assert (ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random"));
-    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
-    android_log_addFilterRule(p_format, "random:w");
-    assert (ANDROID_LOG_WARN == filterPriForTag(p_format, "random"));
-    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
-
-    android_log_addFilterRule(p_format, "crap:*");
-    assert (ANDROID_LOG_VERBOSE== filterPriForTag(p_format, "crap"));
-    assert(android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0);
-
-    // invalid expression
-    err = android_log_addFilterRule(p_format, "random:z");
-    assert (err < 0);
-    assert (ANDROID_LOG_WARN == filterPriForTag(p_format, "random"));
-    assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
-
-    // Issue #550946
-    err = android_log_addFilterString(p_format, " ");
-    assert(err == 0);
-    assert(ANDROID_LOG_WARN == filterPriForTag(p_format, "random"));
-
-    // note trailing space
-    err = android_log_addFilterString(p_format, "*:s random:d ");
-    assert(err == 0);
-    assert(ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random"));
-
-    err = android_log_addFilterString(p_format, "*:s random:z");
-    assert(err < 0);
-
-
-#if 0
-    char *ret;
-    char defaultBuffer[512];
-
-    ret = android_log_formatLogLine(p_format,
-        defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,
-        123, 123, "random", "nofile", strlen("Hello"), "Hello", NULL);
-#endif
-
-
-    fprintf(stderr, "tests complete\n");
-#endif
-}
diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk
index db06cf7..255dc2e 100644
--- a/liblog/tests/Android.mk
+++ b/liblog/tests/Android.mk
@@ -32,7 +32,7 @@
 
 benchmark_src_files := \
     benchmark_main.cpp \
-    liblog_benchmark.cpp \
+    liblog_benchmark.cpp
 
 # Build benchmarks for the device. Run with:
 #   adb shell liblog-benchmarks
@@ -59,10 +59,22 @@
     -g \
     -Wall -Wextra \
     -Werror \
-    -fno-builtin \
+    -fno-builtin
 
 test_src_files := \
-    liblog_test.cpp \
+    liblog_test.cpp
+
+# to prevent breaking the build if bionic not relatively visible to us
+ifneq ($(wildcard $(LOCAL_PATH)/../../../../bionic/libc/bionic/libc_logging.cpp),)
+
+test_src_files += \
+    libc_test.cpp
+
+ifndef ($(TARGET_USES_LOGD),false)
+test_c_flags += -DTARGET_USES_LOGD
+endif
+
+endif
 
 # Build tests for the device (with .so). Run with:
 #   adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests
@@ -71,7 +83,6 @@
 LOCAL_MODULE_TAGS := $(test_tags)
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_CFLAGS += $(test_c_flags)
-LOCAL_LDLIBS := -lpthread
 LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_SRC_FILES := $(test_src_files)
 include $(BUILD_NATIVE_TEST)
diff --git a/liblog/tests/libc_test.cpp b/liblog/tests/libc_test.cpp
new file mode 100644
index 0000000..9839729
--- /dev/null
+++ b/liblog/tests/libc_test.cpp
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+#include <fcntl.h>
+#include <sys/cdefs.h>
+
+#include <gtest/gtest.h>
+
+// Should be in bionic test suite, *but* we are using liblog to confirm
+// end-to-end logging, so let the overly cute oedipus complex begin ...
+#include "../../../../bionic/libc/bionic/libc_logging.cpp" // not Standalone
+#define _ANDROID_LOG_H // Priorities redefined
+#define _LIBS_LOG_LOG_H // log ids redefined
+typedef unsigned char log_id_t; // log_id_t missing as a result
+#ifdef TARGET_USES_LOGD
+#define _LIBS_LOG_LOG_READ_H // log_time redefined
+#endif
+
+#include <log/log.h>
+#include <log/logger.h>
+#include <log/log_read.h>
+
+TEST(libc, __libc_android_log_event_int) {
+    struct logger_list *logger_list;
+
+    pid_t pid = getpid();
+
+    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+        LOG_ID_EVENTS, O_RDONLY | O_NDELAY, 1000, pid)));
+
+    struct timespec ts;
+    clock_gettime(CLOCK_MONOTONIC, &ts);
+    int value = ts.tv_nsec;
+
+    __libc_android_log_event_int(0, value);
+    usleep(1000000);
+
+    int count = 0;
+
+    for (;;) {
+        log_msg log_msg;
+        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
+            break;
+        }
+
+        ASSERT_EQ(log_msg.entry.pid, pid);
+
+        if ((log_msg.entry.len != (4 + 1 + 4))
+         || ((int)log_msg.id() != LOG_ID_EVENTS)) {
+            continue;
+        }
+
+        char *eventData = log_msg.msg();
+
+        int incoming = (eventData[0] & 0xFF) |
+                      ((eventData[1] & 0xFF) << 8) |
+                      ((eventData[2] & 0xFF) << 16) |
+                      ((eventData[3] & 0xFF) << 24);
+
+        if (incoming != 0) {
+            continue;
+        }
+
+        if (eventData[4] != EVENT_TYPE_INT) {
+            continue;
+        }
+
+        incoming = (eventData[4 + 1 + 0] & 0xFF) |
+                  ((eventData[4 + 1 + 1] & 0xFF) << 8) |
+                  ((eventData[4 + 1 + 2] & 0xFF) << 16) |
+                  ((eventData[4 + 1 + 3] & 0xFF) << 24);
+
+        if (incoming == value) {
+            ++count;
+        }
+    }
+
+    EXPECT_EQ(1, count);
+
+    android_logger_list_close(logger_list);
+}
+
+TEST(libc, __libc_fatal_no_abort) {
+    struct logger_list *logger_list;
+
+    pid_t pid = getpid();
+
+    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+        (log_id_t)LOG_ID_CRASH, O_RDONLY | O_NDELAY, 1000, pid)));
+
+    char b[80];
+    struct timespec ts;
+    clock_gettime(CLOCK_MONOTONIC, &ts);
+
+    __libc_fatal_no_abort("%u.%09u", (unsigned)ts.tv_sec, (unsigned)ts.tv_nsec);
+    snprintf(b, sizeof(b),"%u.%09u", (unsigned)ts.tv_sec, (unsigned)ts.tv_nsec);
+    usleep(1000000);
+
+    int count = 0;
+
+    for (;;) {
+        log_msg log_msg;
+        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
+            break;
+        }
+
+        ASSERT_EQ(log_msg.entry.pid, pid);
+
+        if ((int)log_msg.id() != LOG_ID_CRASH) {
+            continue;
+        }
+
+        char *data = log_msg.msg();
+
+        if ((*data == ANDROID_LOG_FATAL)
+                && !strcmp(data + 1, "libc")
+                && !strcmp(data + 1 + strlen(data + 1) + 1, b)) {
+            ++count;
+        }
+    }
+
+    EXPECT_EQ(1, count);
+
+    android_logger_list_close(logger_list);
+}
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
index 39fe2ad..549d79e 100644
--- a/liblog/tests/liblog_benchmark.cpp
+++ b/liblog/tests/liblog_benchmark.cpp
@@ -99,7 +99,7 @@
 }
 BENCHMARK(BM_log_overhead);
 
-static void caught_latency(int signum)
+static void caught_latency(int /*signum*/)
 {
     unsigned long long v = 0xDEADBEEFA55A5AA5ULL;
 
@@ -193,7 +193,7 @@
 }
 BENCHMARK(BM_log_latency);
 
-static void caught_delay(int signum)
+static void caught_delay(int /*signum*/)
 {
     unsigned long long v = 0xDEADBEEFA55A5AA6ULL;
 
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 92b68ac..393e2cd 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -21,6 +21,7 @@
 #include <log/log.h>
 #include <log/logger.h>
 #include <log/log_read.h>
+#include <log/logprint.h>
 
 // enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
 // non-syscall libs. Since we are only using this in the emergency of
@@ -163,7 +164,7 @@
 static unsigned signaled;
 log_time signal_time;
 
-static void caught_blocking(int signum)
+static void caught_blocking(int /*signum*/)
 {
     unsigned long long v = 0xDEADBEEFA55A0000ULL;
 
@@ -543,7 +544,7 @@
     EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag),
               static_cast<size_t>(max_len));
 
-    EXPECT_EQ(ret, max_len + sizeof(big_payload_tag));
+    EXPECT_EQ(ret, max_len + static_cast<ssize_t>(sizeof(big_payload_tag)));
 }
 
 TEST(liblog, dual_reader) {
@@ -612,3 +613,72 @@
 
     android_logger_list_close(logger_list);
 }
+
+static bool checkPriForTag(AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) {
+    return android_log_shouldPrintLine(p_format, tag, pri)
+        && !android_log_shouldPrintLine(p_format, tag, (android_LogPriority)(pri - 1));
+}
+
+TEST(liblog, filterRule) {
+    static const char tag[] = "random";
+
+    AndroidLogFormat *p_format = android_log_format_new();
+
+    android_log_addFilterRule(p_format,"*:i");
+
+    EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
+    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
+    android_log_addFilterRule(p_format, "*");
+    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
+    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
+    android_log_addFilterRule(p_format, "*:v");
+    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
+    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
+    android_log_addFilterRule(p_format, "*:i");
+    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
+    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
+
+    android_log_addFilterRule(p_format, tag);
+    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
+    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
+    android_log_addFilterRule(p_format, "random:v");
+    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
+    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
+    android_log_addFilterRule(p_format, "random:d");
+    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
+    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
+    android_log_addFilterRule(p_format, "random:w");
+    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
+    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
+
+    android_log_addFilterRule(p_format, "crap:*");
+    EXPECT_TRUE (checkPriForTag(p_format, "crap", ANDROID_LOG_VERBOSE));
+    EXPECT_TRUE(android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0);
+
+    // invalid expression
+    EXPECT_TRUE (android_log_addFilterRule(p_format, "random:z") < 0);
+    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
+    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
+
+    // Issue #550946
+    EXPECT_TRUE(android_log_addFilterString(p_format, " ") == 0);
+    EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
+
+    // note trailing space
+    EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:d ") == 0);
+    EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
+
+    EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:z") < 0);
+
+#if 0 // bitrot, seek update
+    char defaultBuffer[512];
+
+    android_log_formatLogLine(p_format,
+        defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,
+        123, 123, tag, "nofile", strlen("Hello"), "Hello", NULL);
+
+    fprintf(stderr, "%s\n", defaultBuffer);
+#endif
+
+    android_log_format_free(p_format);
+}
diff --git a/libmincrypt/dsa_sig.c b/libmincrypt/dsa_sig.c
index 8df6cf7..101314b 100644
--- a/libmincrypt/dsa_sig.c
+++ b/libmincrypt/dsa_sig.c
@@ -26,6 +26,7 @@
 
 #include <string.h>
 
+#include "mincrypt/dsa_sig.h"
 #include "mincrypt/p256.h"
 
 /**
diff --git a/libmincrypt/p256.c b/libmincrypt/p256.c
index 1608d37..555a07a 100644
--- a/libmincrypt/p256.c
+++ b/libmincrypt/p256.c
@@ -49,8 +49,6 @@
   {{0x27d2604b, 0x3bce3c3e, 0xcc53b0f6, 0x651d06b0,
     0x769886bc, 0xb3ebbd55, 0xaa3a93e7, 0x5ac635d8}};
 
-static const p256_int p256_one = P256_ONE;
-
 void p256_init(p256_int* a) {
   memset(a, 0, sizeof(*a));
 }
diff --git a/libmincrypt/test/ecdsa_test.c b/libmincrypt/test/ecdsa_test.c
index b5a7b3a..24ec013 100644
--- a/libmincrypt/test/ecdsa_test.c
+++ b/libmincrypt/test/ecdsa_test.c
@@ -24,15 +24,21 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <stdio.h>
 #include <ctype.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/cdefs.h>
 
+#include "mincrypt/dsa_sig.h"
 #include "mincrypt/p256.h"
 #include "mincrypt/p256_ecdsa.h"
 #include "mincrypt/sha256.h"
 
+#ifndef __unused
+#define __unused __attribute__((__unused__))
+#endif
+
 /**
  * Messages signed using:
  *
@@ -209,7 +215,7 @@
     return result;
 }
 
-int main(int arg, char** argv) {
+int main(int arg __unused, char** argv __unused) {
 
     unsigned char hash_buf[SHA256_DIGEST_SIZE];
 
diff --git a/libmincrypt/test/rsa_test.c b/libmincrypt/test/rsa_test.c
index 17862dc..055138f 100644
--- a/libmincrypt/test/rsa_test.c
+++ b/libmincrypt/test/rsa_test.c
@@ -1,5 +1,4 @@
-/* rsa_test.c
-**
+/*
 ** Copyright 2013, The Android Open Source Project
 **
 ** Redistribution and use in source and binary forms, with or without
@@ -25,14 +24,19 @@
 ** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#include <stdio.h>
 #include <ctype.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/cdefs.h>
 
 #include "mincrypt/rsa.h"
 #include "mincrypt/sha.h"
 
+#ifndef __unused
+#define __unused __attribute__((unused))
+#endif
+
 // RSA test data taken from:
 //
 //   ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt
@@ -791,7 +795,7 @@
 }
 
 
-int main(int arg, char** argv) {
+int main(int arg __unused, char** argv __unused) {
 
     unsigned char hash[SHA_DIGEST_SIZE];
 
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/libsparse/Android.mk b/libsparse/Android.mk
index 9025cc0..02ab412 100644
--- a/libsparse/Android.mk
+++ b/libsparse/Android.mk
@@ -17,6 +17,7 @@
 LOCAL_MODULE := libsparse_host
 LOCAL_STATIC_LIBRARIES := libz
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/include external/zlib
+LOCAL_CFLAGS := -Werror
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 
@@ -27,6 +28,7 @@
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/include external/zlib
 LOCAL_SHARED_LIBRARIES := \
     libz
+LOCAL_CFLAGS := -Werror
 include $(BUILD_SHARED_LIBRARY)
 
 
@@ -36,6 +38,7 @@
 LOCAL_MODULE := libsparse_static
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/include external/zlib
 LOCAL_STATIC_LIBRARIES := libz
+LOCAL_CFLAGS := -Werror
 include $(BUILD_STATIC_LIBRARY)
 
 
@@ -48,6 +51,7 @@
 LOCAL_STATIC_LIBRARIES := \
     libsparse_host \
     libz
+LOCAL_CFLAGS := -Werror
 include $(BUILD_HOST_EXECUTABLE)
 
 
@@ -58,6 +62,7 @@
 LOCAL_STATIC_LIBRARIES := \
     libsparse_static \
     libz
+LOCAL_CFLAGS := -Werror
 include $(BUILD_EXECUTABLE)
 
 
@@ -69,6 +74,7 @@
 LOCAL_STATIC_LIBRARIES := \
     libsparse_host \
     libz
+LOCAL_CFLAGS := -Werror
 include $(BUILD_HOST_EXECUTABLE)
 
 
@@ -78,6 +84,7 @@
 LOCAL_STATIC_LIBRARIES := \
     libsparse_static \
     libz
+LOCAL_CFLAGS := -Werror
 include $(BUILD_EXECUTABLE)
 
 
@@ -87,6 +94,7 @@
 LOCAL_STATIC_LIBRARIES := \
     libsparse_host \
     libz
+LOCAL_CFLAGS := -Werror
 include $(BUILD_HOST_EXECUTABLE)
 
 
@@ -95,5 +103,5 @@
 LOCAL_SRC_FILES := simg_dump.py
 LOCAL_MODULE_CLASS := EXECUTABLES
 LOCAL_IS_HOST_MODULE := true
+LOCAL_CFLAGS := -Werror
 include $(BUILD_PREBUILT)
-
diff --git a/libsparse/img2simg.c b/libsparse/img2simg.c
index 6b1caa5..a0db36f 100644
--- a/libsparse/img2simg.c
+++ b/libsparse/img2simg.c
@@ -47,7 +47,6 @@
 {
 	int in;
 	int out;
-	unsigned int i;
 	int ret;
 	struct sparse_file *s;
 	unsigned int block_size = 4096;
diff --git a/libsparse/output_file.c b/libsparse/output_file.c
index 1cf8d8d..cd30800 100644
--- a/libsparse/output_file.c
+++ b/libsparse/output_file.c
@@ -31,8 +31,8 @@
 
 #include "defs.h"
 #include "output_file.h"
-#include "sparse_format.h"
 #include "sparse_crc32.h"
+#include "sparse_format.h"
 
 #ifndef USE_MINGW
 #include <sys/mman.h>
@@ -295,7 +295,6 @@
 
 static int callback_file_write(struct output_file *out, void *data, int len)
 {
-	int ret;
 	struct output_file_callback *outc = to_output_file_callback(out);
 
 	return outc->write(outc->priv, data, len);
@@ -341,7 +340,7 @@
 static int write_sparse_skip_chunk(struct output_file *out, int64_t skip_len)
 {
 	chunk_header_t chunk_header;
-	int ret, chunk;
+	int ret;
 
 	if (skip_len % out->block_size) {
 		error("don't care size %"PRIi64" is not a multiple of the block size %u",
@@ -368,9 +367,8 @@
 		uint32_t fill_val)
 {
 	chunk_header_t chunk_header;
-	int rnd_up_len, zero_len, count;
+	int rnd_up_len, count;
 	int ret;
-	unsigned int i;
 
 	/* Round up the fill length to a multiple of the block size */
 	rnd_up_len = ALIGN(len, out->block_size);
@@ -536,8 +534,6 @@
 
 void output_file_close(struct output_file *out)
 {
-	int ret;
-
 	out->sparse_ops->write_end_chunk(out);
 	out->ops->close(out);
 }
diff --git a/libsparse/sparse.c b/libsparse/sparse.c
index 0f107b0..baa30cd 100644
--- a/libsparse/sparse.c
+++ b/libsparse/sparse.c
@@ -279,7 +279,6 @@
 		struct sparse_file **out_s, int out_s_count)
 {
 	struct backed_block *bb;
-	unsigned int overhead;
 	struct sparse_file *s;
 	struct sparse_file *tmp;
 	int c = 0;
diff --git a/libsparse/sparse_read.c b/libsparse/sparse_read.c
index 873c87c..8e188e9 100644
--- a/libsparse/sparse_read.c
+++ b/libsparse/sparse_read.c
@@ -180,22 +180,16 @@
 		int fd __unused, unsigned int blocks,
 		unsigned int block __unused, uint32_t *crc32)
 {
-	int ret;
-	int chunk;
-	int64_t len = (int64_t)blocks * s->block_size;
-	uint32_t fill_val;
-	uint32_t *fillbuf;
-	unsigned int i;
-
 	if (chunk_size != 0) {
 		return -EINVAL;
 	}
 
 	if (crc32) {
+	        int64_t len = (int64_t)blocks * s->block_size;
 		memset(copybuf, 0, COPY_BUF_SIZE);
 
 		while (len) {
-			chunk = min(len, COPY_BUF_SIZE);
+			int chunk = min(len, COPY_BUF_SIZE);
 			*crc32 = sparse_crc32(*crc32, copybuf, chunk);
 			len -= chunk;
 		}
@@ -367,7 +361,6 @@
 	int64_t remain = s->len;
 	int64_t offset = 0;
 	unsigned int to_read;
-	char *ptr;
 	unsigned int i;
 	bool sparse_block;
 
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/libsysutils/Android.mk b/libsysutils/Android.mk
index 1451b0d..246f954 100644
--- a/libsysutils/Android.mk
+++ b/libsysutils/Android.mk
@@ -18,7 +18,7 @@
 
 LOCAL_C_INCLUDES :=
 
-LOCAL_CFLAGS :=
+LOCAL_CFLAGS := -Werror
 
 LOCAL_SHARED_LIBRARIES := libcutils liblog
 
diff --git a/libsysutils/EventLogTags.logtags b/libsysutils/EventLogTags.logtags
index 7aa5cad..713f8cd 100644
--- a/libsysutils/EventLogTags.logtags
+++ b/libsysutils/EventLogTags.logtags
@@ -1,5 +1,5 @@
 # See system/core/logcat/event.logtags for a description of the format of this file.
 
 # FrameworkListener dispatchCommand overflow
-78001 dispatchCommand_overflow
-65537 netlink_failure (uid|1)
+78001 exp_det_dispatchCommand_overflow
+65537 exp_det_netlink_failure (uid|1)
diff --git a/libsysutils/src/FrameworkListener.cpp b/libsysutils/src/FrameworkListener.cpp
index 01ed54e..e7b3dd6 100644
--- a/libsysutils/src/FrameworkListener.cpp
+++ b/libsysutils/src/FrameworkListener.cpp
@@ -92,7 +92,6 @@
     char *qlimit = tmp + sizeof(tmp) - 1;
     bool esc = false;
     bool quote = false;
-    int k;
     bool haveCmdNum = !mWithSeq;
 
     memset(argv, 0, sizeof(argv));
@@ -166,7 +165,7 @@
         goto overflow;
     argv[argc++] = strdup(tmp);
 #if 0
-    for (k = 0; k < argc; k++) {
+    for (int k = 0; k < argc; k++) {
         SLOGD("arg[%d] = '%s'", k, argv[k]);
     }
 #endif
diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp
index 34f2016..1c9c70a 100644
--- a/libsysutils/src/NetlinkEvent.cpp
+++ b/libsysutils/src/NetlinkEvent.cpp
@@ -109,7 +109,7 @@
             if (ifaddr->ifa_family == AF_INET) {
                 struct in_addr *addr4 = (struct in_addr *) RTA_DATA(rta);
                 if (RTA_PAYLOAD(rta) < sizeof(*addr4)) {
-                    SLOGE("Short IPv4 address (%d bytes) in %s",
+                    SLOGE("Short IPv4 address (%zu bytes) in %s",
                           RTA_PAYLOAD(rta), msgtype);
                     continue;
                 }
@@ -117,7 +117,7 @@
             } else if (ifaddr->ifa_family == AF_INET6) {
                 struct in6_addr *addr6 = (struct in6_addr *) RTA_DATA(rta);
                 if (RTA_PAYLOAD(rta) < sizeof(*addr6)) {
-                    SLOGE("Short IPv6 address (%d bytes) in %s",
+                    SLOGE("Short IPv6 address (%zu bytes) in %s",
                           RTA_PAYLOAD(rta), msgtype);
                     continue;
                 }
@@ -152,7 +152,7 @@
             }
 
             if (RTA_PAYLOAD(rta) < sizeof(*cacheinfo)) {
-                SLOGE("Short IFA_CACHEINFO (%d vs. %d bytes) in %s",
+                SLOGE("Short IFA_CACHEINFO (%zu vs. %zu bytes) in %s",
                       RTA_PAYLOAD(rta), sizeof(cacheinfo), msgtype);
                 continue;
             }
@@ -174,7 +174,6 @@
 }
 
 /*
-<<<<<<< HEAD
  * Parse a RTM_NEWNDUSEROPT message.
  */
 bool NetlinkEvent::parseNdUserOptMessage(struct nduseroptmsg *msg, int len) {
@@ -399,7 +398,6 @@
     const char *s = buffer;
     const char *end;
     int param_idx = 0;
-    int i;
     int first = 1;
 
     if (size == 0)
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/libusbhost/usbhost.c b/libusbhost/usbhost.c
index 8be393e..cd8000a 100644
--- a/libusbhost/usbhost.c
+++ b/libusbhost/usbhost.c
@@ -263,11 +263,12 @@
                 D("%s subdirectory %s: index: %d\n", (event->mask & IN_CREATE) ?
                         "new" : "gone", path, i);
                 if (i > 0 && i < MAX_USBFS_WD_COUNT) {
+                    int local_ret = 0;
                     if (event->mask & IN_CREATE) {
-                        ret = inotify_add_watch(context->fd, path,
+                        local_ret = inotify_add_watch(context->fd, path,
                                 IN_CREATE | IN_DELETE);
-                        if (ret >= 0)
-                            context->wds[i] = ret;
+                        if (local_ret >= 0)
+                            context->wds[i] = local_ret;
                         done = find_existing_devices_bus(path, context->cb_added,
                                 context->data);
                     } else if (event->mask & IN_DELETE) {
diff --git a/libutils/Android.mk b/libutils/Android.mk
index 1710d36..3afc1ec 100644
--- a/libutils/Android.mk
+++ b/libutils/Android.mk
@@ -43,7 +43,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),),)
@@ -69,7 +69,6 @@
 LOCAL_MODULE:= libutils
 LOCAL_STATIC_LIBRARIES := liblog
 LOCAL_CFLAGS += $(host_commonCflags)
-LOCAL_LDLIBS += $(host_commonLdlibs)
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 
@@ -83,7 +82,6 @@
 LOCAL_MODULE:= lib64utils
 LOCAL_STATIC_LIBRARIES := liblog
 LOCAL_CFLAGS += $(host_commonCflags) -m64
-LOCAL_LDLIBS += $(host_commonLdlibs)
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 
@@ -98,20 +96,15 @@
 	Looper.cpp \
 	Trace.cpp
 
-ifeq ($(TARGET_OS),linux)
-LOCAL_LDLIBS += -lrt -ldl
-endif
-
 ifeq ($(TARGET_ARCH),mips)
 LOCAL_CFLAGS += -DALIGN_DOUBLE
 endif
+LOCAL_CFLAGS += -Werror
 
 LOCAL_C_INCLUDES += \
 		bionic/libc/private \
 		external/zlib
 
-LOCAL_LDLIBS += -lpthread
-
 LOCAL_STATIC_LIBRARIES := \
 	libcutils
 
@@ -134,7 +127,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 8acb4d4..49340bb 100644
--- a/libutils/String8.cpp
+++ b/libutils/String8.cpp
@@ -551,7 +551,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/Android.mk b/libziparchive/Android.mk
index e754c3b..1d48fea 100644
--- a/libziparchive/Android.mk
+++ b/libziparchive/Android.mk
@@ -30,6 +30,7 @@
 LOCAL_MODULE:= libziparchive
 
 LOCAL_C_INCLUDES += ${includes}
+LOCAL_CFLAGS := -Werror
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -40,6 +41,7 @@
 
 LOCAL_STATIC_LIBRARIES := libz libutils
 LOCAL_MODULE:= libziparchive-host
+LOCAL_CFLAGS := -Werror
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -47,7 +49,8 @@
 LOCAL_CPP_EXTENSION := .cc
 LOCAL_CFLAGS += \
     -DGTEST_OS_LINUX_ANDROID \
-    -DGTEST_HAS_STD_STRING
+    -DGTEST_HAS_STD_STRING \
+    -Werror
 LOCAL_SRC_FILES := zip_archive_test.cc
 LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_STATIC_LIBRARIES := libziparchive libz libgtest libgtest_main libutils
@@ -58,7 +61,8 @@
 LOCAL_CPP_EXTENSION := .cc
 LOCAL_CFLAGS += \
     -DGTEST_OS_LINUX \
-    -DGTEST_HAS_STD_STRING
+    -DGTEST_HAS_STD_STRING \
+    -Werror
 LOCAL_SRC_FILES := zip_archive_test.cc
 LOCAL_STATIC_LIBRARIES := libziparchive-host \
 	libz \
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index aebddc8..6781ebe 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -27,6 +27,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <utils/Compat.h>
 #include <utils/FileMap.h>
 #include <zlib.h>
 
@@ -218,7 +219,7 @@
     ssize_t actual = TEMP_FAILURE_RETRY(read(fd, buf, get_size));
 
     if (actual != get_size) {
-      ALOGW("CopyFileToFile: copy read failed (%zd vs %zd)", actual, get_size);
+      ALOGW("CopyFileToFile: copy read failed (" ZD " vs " ZD ")", actual, get_size);
       return kIoError;
     }
 
@@ -337,12 +338,12 @@
   const off64_t search_start = file_length - read_amount;
 
   if (lseek64(fd, search_start, SEEK_SET) != search_start) {
-    ALOGW("Zip: seek %" PRId64 " failed: %s", search_start, strerror(errno));
+    ALOGW("Zip: seek %" PRId64 " failed: %s", (int64_t)search_start, strerror(errno));
     return kIoError;
   }
   ssize_t actual = TEMP_FAILURE_RETRY(read(fd, scan_buffer, read_amount));
   if (actual != (ssize_t) read_amount) {
-    ALOGW("Zip: read %u failed: %s", read_amount, strerror(errno));
+    ALOGW("Zip: read %" PRIu32 " failed: %s", read_amount, strerror(errno));
     return kIoError;
   }
 
@@ -380,7 +381,7 @@
 
   if (dir_offset + dir_size > eocd_offset) {
     ALOGW("Zip: bad offsets (dir %" PRId64 ", size %" PRId64 ", eocd %" PRId64 ")",
-        dir_offset, dir_size, eocd_offset);
+        (int64_t)dir_offset, (int64_t)dir_size, (int64_t)eocd_offset);
     return kInvalidOffset;
   }
   if (num_entries == 0) {
@@ -389,7 +390,7 @@
   }
 
   ALOGV("+++ num_entries=%d dir_size=%" PRId64 " dir_offset=%" PRId64,
-        num_entries, dir_size, dir_offset);
+        num_entries, (int64_t)dir_size, (int64_t)dir_offset);
 
   /*
    * It all looks good.  Create a mapping for the CD, and set the fields
@@ -430,12 +431,12 @@
   }
 
   if (file_length > (off64_t) 0xffffffff) {
-    ALOGV("Zip: zip file too long %" PRId64, file_length);
+    ALOGV("Zip: zip file too long %" PRId64, (int64_t)file_length);
     return kInvalidFile;
   }
 
   if (file_length < (int64_t) kEOCDLen) {
-    ALOGV("Zip: length %" PRId64 " is too small to be zip", file_length);
+    ALOGV("Zip: length %" PRId64 " is too small to be zip", (int64_t)file_length);
     return kInvalidFile;
   }
 
@@ -492,18 +493,18 @@
   const uint8_t* ptr = cd_ptr;
   for (uint16_t i = 0; i < num_entries; i++) {
     if (get4LE(ptr) != kCDESignature) {
-      ALOGW("Zip: missed a central dir sig (at %d)", i);
+      ALOGW("Zip: missed a central dir sig (at %" PRIu16 ")", i);
       goto bail;
     }
 
     if (ptr + kCDELen > cd_ptr + cd_length) {
-      ALOGW("Zip: ran off the end (at %d)", i);
+      ALOGW("Zip: ran off the end (at %" PRIu16 ")", i);
       goto bail;
     }
 
     const off64_t local_header_offset = get4LE(ptr + kCDELocalOffset);
     if (local_header_offset >= archive->directory_offset) {
-      ALOGW("Zip: bad LFH offset %" PRId64 " at entry %d", local_header_offset, i);
+      ALOGW("Zip: bad LFH offset %" PRId64 " at entry %" PRIu16, (int64_t)local_header_offset, i);
       goto bail;
     }
 
@@ -522,12 +523,12 @@
 
     ptr += kCDELen + file_name_length + extra_length + comment_length;
     if ((size_t)(ptr - cd_ptr) > cd_length) {
-      ALOGW("Zip: bad CD advance (%zu vs %zu) at entry %d",
-        (size_t) (ptr - cd_ptr), cd_length, i);
+      ALOGW("Zip: bad CD advance (%tu vs %zu) at entry %" PRIu16,
+          ptr - cd_ptr, cd_length, i);
       goto bail;
     }
   }
-  ALOGV("+++ zip good scan %d entries", num_entries);
+  ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries);
 
   result = 0;
 
@@ -686,13 +687,13 @@
   ssize_t actual = ReadAtOffset(archive->fd, lfh_buf, sizeof(lfh_buf),
                                  local_header_offset);
   if (actual != sizeof(lfh_buf)) {
-    ALOGW("Zip: failed reading lfh name from offset %" PRId64, local_header_offset);
+    ALOGW("Zip: failed reading lfh name from offset %" PRId64, (int64_t)local_header_offset);
     return kIoError;
   }
 
   if (get4LE(lfh_buf) != kLFHSignature) {
     ALOGW("Zip: didn't find signature at start of lfh, offset=%" PRId64,
-        local_header_offset);
+        (int64_t)local_header_offset);
     return kInvalidOffset;
   }
 
@@ -710,7 +711,8 @@
     data->has_data_descriptor = 0;
     if (data->compressed_length != lfhCompLen || data->uncompressed_length != lfhUncompLen
         || data->crc32 != lfhCrc) {
-      ALOGW("Zip: size/crc32 mismatch. expected {%d, %d, %x}, was {%d, %d, %x}",
+      ALOGW("Zip: size/crc32 mismatch. expected {%" PRIu32 ", %" PRIu32
+        ", %" PRIx32 "}, was {%" PRIu32 ", %" PRIu32 ", %" PRIx32 "}",
         data->compressed_length, data->uncompressed_length, data->crc32,
         lfhCompLen, lfhUncompLen, lfhCrc);
       return kInconsistentInformation;
@@ -733,7 +735,7 @@
                                   name_offset);
 
     if (actual != nameLen) {
-      ALOGW("Zip: failed reading lfh name from offset %" PRId64, name_offset);
+      ALOGW("Zip: failed reading lfh name from offset %" PRId64, (int64_t)name_offset);
       free(name_buf);
       return kIoError;
     }
@@ -751,20 +753,20 @@
 
   const off64_t data_offset = local_header_offset + kLFHLen + lfhNameLen + lfhExtraLen;
   if (data_offset > cd_offset) {
-    ALOGW("Zip: bad data offset %" PRId64 " in zip", data_offset);
+    ALOGW("Zip: bad data offset %" PRId64 " in zip", (int64_t)data_offset);
     return kInvalidOffset;
   }
 
   if ((off64_t)(data_offset + data->compressed_length) > cd_offset) {
-    ALOGW("Zip: bad compressed length in zip (%" PRId64 " + %zd > %" PRId64 ")",
-      data_offset, data->compressed_length, cd_offset);
+    ALOGW("Zip: bad compressed length in zip (%" PRId64 " + %" PRIu32 " > %" PRId64 ")",
+      (int64_t)data_offset, data->compressed_length, (int64_t)cd_offset);
     return kInvalidOffset;
   }
 
   if (data->method == kCompressStored &&
     (off64_t)(data_offset + data->uncompressed_length) > cd_offset) {
-     ALOGW("Zip: bad uncompressed length in zip (%" PRId64 " + %d > %" PRId64 ")",
-       data_offset, data->uncompressed_length, cd_offset);
+     ALOGW("Zip: bad uncompressed length in zip (%" PRId64 " + %" PRIu32 " > %" PRId64 ")",
+       (int64_t)data_offset, data->uncompressed_length, (int64_t)cd_offset);
      return kInvalidOffset;
   }
 
@@ -900,10 +902,10 @@
   do {
     /* read as much as we can */
     if (zstream.avail_in == 0) {
-      const ssize_t getSize = (compressed_length > kBufSize) ? kBufSize : compressed_length;
-      const ssize_t actual = TEMP_FAILURE_RETRY(read(fd, read_buf, getSize));
+      const ZD_TYPE getSize = (compressed_length > kBufSize) ? kBufSize : compressed_length;
+      const ZD_TYPE actual = TEMP_FAILURE_RETRY(read(fd, read_buf, getSize));
       if (actual != getSize) {
-        ALOGW("Zip: inflate read failed (%zd vs %zd)", actual, getSize);
+        ALOGW("Zip: inflate read failed (" ZD " vs " ZD ")", actual, getSize);
         result = kIoError;
         goto z_bail;
       }
@@ -946,7 +948,7 @@
   *crc_out = zstream.adler;
 
   if (zstream.total_out != uncompressed_length || compressed_length != 0) {
-    ALOGW("Zip: size mismatch on inflated file (%ld vs %u)",
+    ALOGW("Zip: size mismatch on inflated file (%lu vs %" PRIu32 ")",
         zstream.total_out, uncompressed_length);
     result = kInconsistentInformation;
     goto z_bail;
@@ -967,7 +969,7 @@
   off64_t data_offset = entry->offset;
 
   if (lseek64(archive->fd, data_offset, SEEK_SET) != data_offset) {
-    ALOGW("Zip: lseek to data at %" PRId64 " failed", data_offset);
+    ALOGW("Zip: lseek to data at %" PRId64 " failed", (int64_t)data_offset);
     return kIoError;
   }
 
@@ -990,7 +992,7 @@
   // TODO: Fix this check by passing the right flags to inflate2 so that
   // it calculates the CRC for us.
   if (entry->crc32 != crc && false) {
-    ALOGW("Zip: crc mismatch: expected %u, was %" PRIu64, entry->crc32, crc);
+    ALOGW("Zip: crc mismatch: expected %" PRIu32 ", was %" PRIu64, entry->crc32, crc);
     return kInconsistentInformation;
   }
 
@@ -1011,7 +1013,7 @@
   int result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
   if (result == -1) {
     ALOGW("Zip: unable to truncate file to %" PRId64 ": %s",
-          declared_length + current_offset, strerror(errno));
+          (int64_t)(declared_length + current_offset), strerror(errno));
     return kIoError;
   }
 
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index 3082216..2eb9318 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -209,7 +209,8 @@
                       sizeof(kATxtContents)));
 
   // Assert that the total length of the file is sane
-  ASSERT_EQ(data_size + sizeof(kATxtContents), lseek64(fd, 0, SEEK_END));
+  ASSERT_EQ(data_size + static_cast<ssize_t>(sizeof(kATxtContents)),
+            lseek64(fd, 0, SEEK_END));
 
   close(fd);
 }
@@ -247,4 +248,3 @@
 
   return RUN_ALL_TESTS();
 }
-
diff --git a/libzipfile/Android.mk b/libzipfile/Android.mk
index d2d758c..614a460 100644
--- a/libzipfile/Android.mk
+++ b/libzipfile/Android.mk
@@ -14,6 +14,8 @@
 
 LOCAL_C_INCLUDES += external/zlib
 
+LOCAL_CFLAGS := -Werror
+
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 # build device static library
@@ -30,6 +32,8 @@
 
 LOCAL_C_INCLUDES += external/zlib
 
+LOCAL_CFLAGS := -Werror
+
 include $(BUILD_STATIC_LIBRARY)
 
 
@@ -45,4 +49,6 @@
 
 LOCAL_C_INCLUDES += external/zlib
 
+LOCAL_CFLAGS := -Werror
+
 include $(BUILD_HOST_EXECUTABLE)
diff --git a/libzipfile/centraldir.c b/libzipfile/centraldir.c
index 911e2b9..69cf47a 100644
--- a/libzipfile/centraldir.c
+++ b/libzipfile/centraldir.c
@@ -3,6 +3,8 @@
 #include <string.h>

 #include <stdlib.h>

 

+#include <utils/Compat.h>

+

 enum {

     // finding the directory

     CD_SIGNATURE = 0x06054b50,

@@ -66,24 +68,10 @@
 {

     const unsigned char* p;

 

-    unsigned short  versionMadeBy;

-    unsigned short  versionToExtract;

-    unsigned short  gpBitFlag;

-    unsigned short  compressionMethod;

-    unsigned short  lastModFileTime;

-    unsigned short  lastModFileDate;

-    unsigned long   crc32;

     unsigned short  extraFieldLength;

     unsigned short  fileCommentLength;

-    unsigned short  diskNumberStart;

-    unsigned short  internalAttrs;

-    unsigned long   externalAttrs;

     unsigned long   localHeaderRelOffset;

-    const unsigned char*  extraField;

-    const unsigned char*  fileComment;

     unsigned int dataOffset;

-    unsigned short lfhExtraFieldSize;

-

 

     p = *buf;

 

@@ -97,21 +85,12 @@
         return -1;

     }

 

-    versionMadeBy = read_le_short(&p[0x04]);

-    versionToExtract = read_le_short(&p[0x06]);

-    gpBitFlag = read_le_short(&p[0x08]);

     entry->compressionMethod = read_le_short(&p[0x0a]);

-    lastModFileTime = read_le_short(&p[0x0c]);

-    lastModFileDate = read_le_short(&p[0x0e]);

-    crc32 = read_le_int(&p[0x10]);

     entry->compressedSize = read_le_int(&p[0x14]);

     entry->uncompressedSize = read_le_int(&p[0x18]);

     entry->fileNameLength = read_le_short(&p[0x1c]);

     extraFieldLength = read_le_short(&p[0x1e]);

     fileCommentLength = read_le_short(&p[0x20]);

-    diskNumberStart = read_le_short(&p[0x22]);

-    internalAttrs = read_le_short(&p[0x24]);

-    externalAttrs = read_le_int(&p[0x26]);

     localHeaderRelOffset = read_le_int(&p[0x2a]);

 

     p += ENTRY_LEN;

@@ -125,19 +104,9 @@
     p += entry->fileNameLength;

 

     // extra field

-    if (extraFieldLength != 0) {

-        extraField = p;

-    } else {

-        extraField = NULL;

-    }

     p += extraFieldLength;

 

     // comment, if any

-    if (fileCommentLength != 0) {

-        fileComment = p;

-    } else {

-        fileComment = NULL;

-    }

     p += fileCommentLength;

 

     *buf = p;

@@ -183,7 +152,7 @@
     int err;

 

     const unsigned char* buf = file->buf;

-    ssize_t bufsize = file->bufsize;

+    ZD_TYPE bufsize = file->bufsize;

     const unsigned char* eocd;

     const unsigned char* p;

     const unsigned char* start;

@@ -192,7 +161,7 @@
 

     // too small to be a ZIP archive?

     if (bufsize < EOCD_LEN) {

-        fprintf(stderr, "Length is %zd -- too small\n", bufsize);

+        fprintf(stderr, "Length is " ZD " -- too small\n", bufsize);

         goto bail;

     }

 

diff --git a/libzipfile/zipfile.c b/libzipfile/zipfile.c
index a401a9b..b903fcf 100644
--- a/libzipfile/zipfile.c
+++ b/libzipfile/zipfile.c
@@ -79,7 +79,6 @@
 uninflate(unsigned char* out, int unlen, const unsigned char* in, int clen)
 {
     z_stream zstream;
-    unsigned long crc;
     int err = 0;
     int zerr;
 
diff --git a/logcat/Android.mk b/logcat/Android.mk
index b5e27eb..f46a4de 100644
--- a/logcat/Android.mk
+++ b/logcat/Android.mk
@@ -7,7 +7,9 @@
 
 LOCAL_SHARED_LIBRARIES := liblog
 
-LOCAL_MODULE:= logcat
+LOCAL_MODULE := logcat
+
+LOCAL_CFLAGS := -Werror
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 995a42e..16fe7ee 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -281,7 +281,29 @@
     return 0;
 }
 
-extern "C" void logprint_run_tests(void);
+static const char multipliers[][2] = {
+    { "" },
+    { "K" },
+    { "M" },
+    { "G" }
+};
+
+static unsigned long value_of_size(unsigned long value)
+{
+    for (unsigned i = 0;
+            (i < sizeof(multipliers)/sizeof(multipliers[0])) && (value >= 1024);
+            value /= 1024, ++i) ;
+    return value;
+}
+
+static const char *multiplier_of_size(unsigned long value)
+{
+    unsigned i;
+    for (i = 0;
+            (i < sizeof(multipliers)/sizeof(multipliers[0])) && (value >= 1024);
+            value /= 1024, ++i) ;
+    return multipliers[i];
+}
 
 int main(int argc, char **argv)
 {
@@ -306,11 +328,6 @@
 
     g_logformat = android_log_format_new();
 
-    if (argc == 2 && 0 == strcmp(argv[1], "--test")) {
-        logprint_run_tests();
-        exit(0);
-    }
-
     if (argc == 2 && 0 == strcmp(argv[1], "--help")) {
         android::show_help(argv[0]);
         exit(0);
@@ -496,9 +513,6 @@
                     android::g_logRotateSizeKBytes
                                 = DEFAULT_LOG_ROTATE_SIZE_KBYTES;
                 } else {
-                    long logRotateSize;
-                    char *lastDigit;
-
                     if (!isdigit(optarg[0])) {
                         fprintf(stderr,"Invalid parameter to -r\n");
                         android::show_help(argv[0]);
@@ -609,18 +623,14 @@
     }
 
     if (!devices) {
-        devices = new log_device_t("main", false, 'm');
+        dev = devices = new log_device_t("main", false, 'm');
         android::g_devCount = 1;
         if (android_name_to_log_id("system") == LOG_ID_SYSTEM) {
-            devices->next = new log_device_t("system", false, 's');
+            dev = dev->next = new log_device_t("system", false, 's');
             android::g_devCount++;
         }
         if (android_name_to_log_id("crash") == LOG_ID_CRASH) {
-            if (devices->next) {
-                devices->next->next = new log_device_t("crash", false, 'c');
-            } else {
-                devices->next = new log_device_t("crash", false, 'c');
-            }
+            dev = dev->next = new log_device_t("crash", false, 'c');
             android::g_devCount++;
         }
     }
@@ -725,9 +735,10 @@
                 exit(EXIT_FAILURE);
             }
 
-            printf("%s: ring buffer is %ldKb (%ldKb consumed), "
+            printf("%s: ring buffer is %ld%sb (%ld%sb consumed), "
                    "max entry is %db, max payload is %db\n", dev->device,
-                   size / 1024, readable / 1024,
+                   value_of_size(size), multiplier_of_size(size),
+                   value_of_size(readable), multiplier_of_size(readable),
                    (int) LOGGER_ENTRY_MAX_LEN, (int) LOGGER_ENTRY_MAX_PAYLOAD);
         }
 
diff --git a/logcat/tests/Android.mk b/logcat/tests/Android.mk
index d42b3d0..5d4d29e 100644
--- a/logcat/tests/Android.mk
+++ b/logcat/tests/Android.mk
@@ -40,7 +40,6 @@
 LOCAL_MODULE_TAGS := $(test_tags)
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_CFLAGS += $(test_c_flags)
-LOCAL_LDLIBS := -lpthread
 LOCAL_SHARED_LIBRARIES := liblog
 LOCAL_SRC_FILES := $(test_src_files)
 include $(BUILD_NATIVE_TEST)
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index b07cc8b..2e8ae8b 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -392,7 +392,7 @@
     ASSERT_EQ(4, count);
 }
 
-static void caught_blocking(int signum)
+static void caught_blocking(int /*signum*/)
 {
     unsigned long long v = 0xDEADBEEFA55A0000ULL;
 
@@ -461,7 +461,7 @@
     EXPECT_EQ(1, signals);
 }
 
-static void caught_blocking_tail(int signum)
+static void caught_blocking_tail(int /*signum*/)
 {
     unsigned long long v = 0xA55ADEADBEEF0000ULL;
 
@@ -532,7 +532,7 @@
     EXPECT_EQ(1, signals);
 }
 
-static void caught_blocking_clear(int signum)
+static void caught_blocking_clear(int /*signum*/)
 {
     unsigned long long v = 0xDEADBEEFA55C0000ULL;
 
diff --git a/logd/Android.mk b/logd/Android.mk
index 0235478..188511f 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -17,7 +17,8 @@
     LogStatistics.cpp \
     LogWhiteBlackList.cpp \
     libaudit.c \
-    LogAudit.cpp
+    LogAudit.cpp \
+    event.logtags
 
 LOCAL_SHARED_LIBRARIES := \
     libsysutils \
@@ -25,7 +26,7 @@
     libcutils \
     libutils
 
-LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := -Werror $(shell sed -n 's/^\([0-9]*\)[ \t]*auditd[ \t].*/-DAUDITD_LOG_TAG=\1/p' $(LOCAL_PATH)/event.logtags)
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp
index a7bf92b..9d7d152 100644
--- a/logd/CommandListener.cpp
+++ b/logd/CommandListener.cpp
@@ -21,6 +21,7 @@
 #include <netinet/in.h>
 #include <string.h>
 #include <stdlib.h>
+#include <sys/prctl.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 
@@ -66,8 +67,13 @@
         , mBuf(*buf)
 { }
 
+static void setname() {
+    prctl(PR_SET_NAME, "logd.control");
+}
+
 int CommandListener::ClearCmd::runCommand(SocketClient *cli,
                                          int argc, char **argv) {
+    setname();
     if (!clientHasLogCredentials(cli)) {
         cli->sendMsg("Permission Denied");
         return 0;
@@ -96,6 +102,7 @@
 
 int CommandListener::GetBufSizeCmd::runCommand(SocketClient *cli,
                                          int argc, char **argv) {
+    setname();
     if (argc < 2) {
         cli->sendMsg("Missing Argument");
         return 0;
@@ -121,6 +128,7 @@
 
 int CommandListener::SetBufSizeCmd::runCommand(SocketClient *cli,
                                          int argc, char **argv) {
+    setname();
     if (!clientHasLogCredentials(cli)) {
         cli->sendMsg("Permission Denied");
         return 0;
@@ -154,6 +162,7 @@
 
 int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient *cli,
                                          int argc, char **argv) {
+    setname();
     if (argc < 2) {
         cli->sendMsg("Missing Argument");
         return 0;
@@ -197,8 +206,8 @@
 
 int CommandListener::GetStatisticsCmd::runCommand(SocketClient *cli,
                                          int argc, char **argv) {
+    setname();
     uid_t uid = cli->getUid();
-    gid_t gid = cli->getGid();
     if (clientHasLogCredentials(cli)) {
         uid = AID_ROOT;
     }
@@ -236,6 +245,7 @@
 
 int CommandListener::GetPruneListCmd::runCommand(SocketClient *cli,
                                          int /*argc*/, char ** /*argv*/) {
+    setname();
     char *buf = NULL;
     mBuf.formatPrune(&buf);
     if (!buf) {
@@ -255,6 +265,7 @@
 
 int CommandListener::SetPruneListCmd::runCommand(SocketClient *cli,
                                          int argc, char **argv) {
+    setname();
     if (!clientHasLogCredentials(cli)) {
         cli->sendMsg("Permission Denied");
         return 0;
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index ea6eece..f8d6162 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -16,9 +16,11 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <limits.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <sys/klog.h>
+#include <sys/prctl.h>
 #include <sys/uio.h>
 
 #include "libaudit.h"
@@ -34,8 +36,14 @@
 }
 
 bool LogAudit::onDataAvailable(SocketClient *cli) {
+    prctl(PR_SET_NAME, "logd.auditd");
+
     struct audit_message rep;
 
+    rep.nlh.nlmsg_type = 0;
+    rep.nlh.nlmsg_len = 0;
+    rep.data[0] = '\0';
+
     if (audit_get_reply(cli->getSocket(), &rep, GET_REPLY_BLOCKING, 0) < 0) {
         SLOGE("Failed on audit_get_reply with error: %s", strerror(errno));
         return false;
@@ -46,9 +54,6 @@
     return true;
 }
 
-#define AUDIT_LOG_ID   LOG_ID_MAIN
-#define AUDIT_LOG_PRIO ANDROID_LOG_WARN
-
 int LogAudit::logPrint(const char *fmt, ...) {
     if (fmt == NULL) {
         return -EINVAL;
@@ -65,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];
 
@@ -83,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
     }
@@ -104,53 +113,88 @@
         }
         tid = pid;
         uid = logbuf->pidToUid(pid);
-        strcpy(pidptr, cp);
+        memmove(pidptr, cp, strlen(cp) + 1);
     }
 
-    static const char comm_str[] = " comm=\"";
-    char *comm = strstr(str, comm_str);
-    if (comm) {
-        cp = comm;
-        comm += sizeof(comm_str) - 1;
-        char *ecomm = strchr(comm, '"');
-        if (ecomm) {
-            *ecomm = '\0';
-        }
-        comm = strdup(comm);
-        if (ecomm) {
-            strcpy(cp, ecomm + 1);
-        }
-    } else if (pid == getpid()) {
-        pid = tid;
-        comm = strdup("auditd");
-    } else if (!(comm = logbuf->pidToName(pid))) {
-        comm = strdup("unknown");
-    }
+    // log to events
 
-    size_t l = strlen(comm) + 1;
-    size_t n = l + strlen(str) + 2;
+    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(comm);
-        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;
     }
 
-    *newstr = AUDIT_LOG_PRIO;
-    strcpy(newstr + 1, comm);
-    free(comm);
-    strcpy(newstr + 1 + l, str);
+    // 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);
 
-    unsigned short len = n; // cap to internal maximum
-    if (len != n) {
-        len = -1;
+    if (notify) {
+        reader->notifyNewLog();
     }
-    logbuf->log(AUDIT_LOG_ID, now, uid, pid, tid, newstr, len);
-    reader->notifyNewLog();
-
-    free(newstr);
 
     return rc;
 }
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 8dcab87..0448afa 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -14,29 +14,121 @@
  * limitations under the License.
  */
 
+#include <ctype.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
+#include <sys/user.h>
 #include <time.h>
 #include <unistd.h>
 
+#include <cutils/properties.h>
 #include <log/logger.h>
 
 #include "LogBuffer.h"
+#include "LogReader.h"
 #include "LogStatistics.h"
 #include "LogWhiteBlackList.h"
-#include "LogReader.h"
 
 // Default
 #define LOG_BUFFER_SIZE (256 * 1024) // Tuned on a per-platform basis here?
 #define log_buffer_size(id) mMaxSize[id]
+#define LOG_BUFFER_MIN_SIZE (64 * 1024UL)
+#define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL)
+
+static bool valid_size(unsigned long value) {
+    if ((value < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < value)) {
+        return false;
+    }
+
+    long pages = sysconf(_SC_PHYS_PAGES);
+    if (pages < 1) {
+        return true;
+    }
+
+    long pagesize = sysconf(_SC_PAGESIZE);
+    if (pagesize <= 1) {
+        pagesize = PAGE_SIZE;
+    }
+
+    // maximum memory impact a somewhat arbitrary ~3%
+    pages = (pages + 31) / 32;
+    unsigned long maximum = pages * pagesize;
+
+    if ((maximum < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < maximum)) {
+        return true;
+    }
+
+    return value <= maximum;
+}
+
+static unsigned long property_get_size(const char *key) {
+    char property[PROPERTY_VALUE_MAX];
+    property_get(key, property, "");
+
+    char *cp;
+    unsigned long value = strtoul(property, &cp, 10);
+
+    switch(*cp) {
+    case 'm':
+    case 'M':
+        value *= 1024;
+    /* FALLTHRU */
+    case 'k':
+    case 'K':
+        value *= 1024;
+    /* FALLTHRU */
+    case '\0':
+        break;
+
+    default:
+        value = 0;
+    }
+
+    if (!valid_size(value)) {
+        value = 0;
+    }
+
+    return value;
+}
 
 LogBuffer::LogBuffer(LastLogTimes *times)
         : mTimes(*times) {
     pthread_mutex_init(&mLogElementsLock, NULL);
     dgram_qlen_statistics = false;
 
+    static const char global_tuneable[] = "persist.logd.size"; // Settings App
+    static const char global_default[] = "ro.logd.size";       // BoardConfig.mk
+
+    unsigned long default_size = property_get_size(global_tuneable);
+    if (!default_size) {
+        default_size = property_get_size(global_default);
+    }
+
     log_id_for_each(i) {
-        mMaxSize[i] = LOG_BUFFER_SIZE;
+        char key[PROP_NAME_MAX];
+
+        snprintf(key, sizeof(key), "%s.%s",
+                 global_tuneable, android_log_id_to_name(i));
+        unsigned long property_size = property_get_size(key);
+
+        if (!property_size) {
+            snprintf(key, sizeof(key), "%s.%s",
+                     global_default, android_log_id_to_name(i));
+            property_size = property_get_size(key);
+        }
+
+        if (!property_size) {
+            property_size = default_size;
+        }
+
+        if (!property_size) {
+            property_size = LOG_BUFFER_SIZE;
+        }
+
+        if (setSize(i, property_size)) {
+            setSize(i, LOG_BUFFER_MIN_SIZE);
+        }
     }
 }
 
@@ -82,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;
 
@@ -167,17 +259,14 @@
 
         if ((id != LOG_ID_CRASH) && mPrune.worstUidEnabled()) {
             LidStatistics &l = stats.id(id);
-            UidStatisticsCollection::iterator iu;
-            for (iu = l.begin(); iu != l.end(); ++iu) {
-                UidStatistics *u = (*iu);
-                size_t sizes = u->sizes();
-                if (worst_sizes < sizes) {
-                    second_worst_sizes = worst_sizes;
-                    worst_sizes = sizes;
-                    worst = u->getUid();
-                }
-                if ((second_worst_sizes < sizes) && (sizes < worst_sizes)) {
-                    second_worst_sizes = sizes;
+            l.sort();
+            UidStatisticsCollection::iterator iu = l.begin();
+            if (iu != l.end()) {
+                UidStatistics *u = *iu;
+                worst = u->getUid();
+                worst_sizes = u->sizes();
+                if (++iu != l.end()) {
+                    second_worst_sizes = (*iu)->sizes();
                 }
             }
         }
@@ -303,7 +392,7 @@
 // set the total space allocated to "id"
 int LogBuffer::setSize(log_id_t id, unsigned long size) {
     // Reasonable limits ...
-    if ((size < (64 * 1024)) || ((256 * 1024 * 1024) < size)) {
+    if (!valid_size(size)) {
         return -1;
     }
     pthread_mutex_lock(&mLogElementsLock);
diff --git a/logd/LogCommand.cpp b/logd/LogCommand.cpp
index 0873e63..e4c138e 100644
--- a/logd/LogCommand.cpp
+++ b/logd/LogCommand.cpp
@@ -64,7 +64,7 @@
     }
 
     gid_t gid = cli->getGid();
-    if ((gid == AID_ROOT) || (gid == AID_LOG)) {
+    if ((gid == AID_ROOT) || (gid == AID_SYSTEM) || (gid == AID_LOG)) {
         return true;
     }
 
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
index 1d0a51c..8186cea 100644
--- a/logd/LogListener.cpp
+++ b/logd/LogListener.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <limits.h>
+#include <sys/prctl.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/un.h>
@@ -31,6 +33,8 @@
 {  }
 
 bool LogListener::onDataAvailable(SocketClient *cli) {
+    prctl(PR_SET_NAME, "logd.writer");
+
     char buffer[sizeof_log_id_t + sizeof(uint16_t) + sizeof(log_time)
         + LOGGER_ENTRY_MAX_PAYLOAD];
     struct iovec iov = { buffer, sizeof(buffer) };
@@ -97,11 +101,10 @@
 
     // NB: hdr.msg_flags & MSG_TRUNC is not tested, silently passing a
     // truncated message to the logs.
-    unsigned short len = n; // cap to internal maximum
-    if (len == n) {
-        logbuf->log(log_id, realtime, cred->uid, cred->pid, tid, msg, len);
-        reader->notifyNewLog();
-    }
+
+    logbuf->log(log_id, realtime, cred->uid, cred->pid, tid, msg,
+        ((size_t) n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX);
+    reader->notifyNewLog();
 
     return true;
 }
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
index 51aa2ad..8458c19 100644
--- a/logd/LogReader.cpp
+++ b/logd/LogReader.cpp
@@ -16,6 +16,7 @@
 
 #include <ctype.h>
 #include <poll.h>
+#include <sys/prctl.h>
 #include <sys/socket.h>
 
 #include <cutils/sockets.h>
@@ -36,6 +37,8 @@
 }
 
 bool LogReader::onDataAvailable(SocketClient *cli) {
+    prctl(PR_SET_NAME, "logd.reader");
+
     char buffer[255];
 
     int len = read(cli->getSocket(), buffer, sizeof(buffer) - 1);
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index 5146030..81c9bab 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -31,6 +31,7 @@
         , mSizes(0)
         , mElements(0)
         , name(name)
+        , mGone(false)
 { }
 
 #ifdef DO_NOT_ERROR_IF_PIDSTATISTICS_USES_A_COPY_CONSTRUCTOR
@@ -41,6 +42,7 @@
         , mElementsTotal(copy->mElementsTotal)
         , mSizes(copy->mSizes)
         , mElements(copy->mElements)
+        , mGone(copy->mGone)
 { }
 #endif
 
@@ -48,6 +50,20 @@
     free(name);
 }
 
+bool PidStatistics::pidGone() {
+    if (mGone) {
+        return true;
+    }
+    if (pid == gone) {
+        return true;
+    }
+    if (kill(pid, 0) && (errno != EPERM)) {
+        mGone = true;
+        return true;
+    }
+    return false;
+}
+
 void PidStatistics::setName(char *new_name) {
     free(name);
     name = new_name;
@@ -63,7 +79,7 @@
 bool PidStatistics::subtract(unsigned short size) {
     mSizes -= size;
     --mElements;
-    return (mElements == 0) && kill(pid, 0) && (errno != EPERM);
+    return (mElements == 0) && pidGone();
 }
 
 void PidStatistics::addTotal(size_t size, size_t element) {
@@ -76,7 +92,7 @@
 // must call free to release return value
 char *PidStatistics::pidToName(pid_t pid) {
     char *retval = NULL;
-    if (pid != PidStatistics::gone) {
+    if (pid != gone) {
         char buffer[512];
         snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
         int fd = open(buffer, O_RDONLY);
@@ -96,7 +112,9 @@
 }
 
 UidStatistics::UidStatistics(uid_t uid)
-        : uid(uid) {
+        : uid(uid)
+        , mSizes(0)
+        , mElements(0) {
     Pids.clear();
 }
 
@@ -109,6 +127,9 @@
 }
 
 void UidStatistics::add(unsigned short size, pid_t pid) {
+    mSizes += size;
+    ++mElements;
+
     PidStatistics *p;
     PidStatisticsCollection::iterator last;
     PidStatisticsCollection::iterator it;
@@ -116,18 +137,11 @@
         p = *it;
         if (pid == p->getPid()) {
             p->add(size);
-            // poor-man sort, bubble upwards if bigger than last
-            if ((last != it) && ((*last)->sizesTotal() < p->sizesTotal())) {
-                Pids.erase(it);
-                Pids.insert(last, p);
-            }
             return;
         }
     }
-    // poor-man sort, insert if bigger than last or last is the gone entry.
-    bool insert = (last != it)
-        && ((p->getPid() == p->gone)
-            || ((*last)->sizesTotal() < (size_t) size));
+    // insert if the gone entry.
+    bool insert = (last != it) && (p->getPid() == p->gone);
     p = new PidStatistics(pid, pidToName(pid));
     if (insert) {
         Pids.insert(last, p);
@@ -138,6 +152,9 @@
 }
 
 void UidStatistics::subtract(unsigned short size, pid_t pid) {
+    mSizes -= size;
+    --mElements;
+
     PidStatisticsCollection::iterator it;
     for (it = begin(); it != end(); ++it) {
         PidStatistics *p = *it;
@@ -166,28 +183,57 @@
     }
 }
 
+void UidStatistics::sort() {
+    for (bool pass = true; pass;) {
+        pass = false;
+        PidStatisticsCollection::iterator it = begin();
+        if (it != end()) {
+            PidStatisticsCollection::iterator lt = it;
+            PidStatistics *l = (*lt);
+            while (++it != end()) {
+                PidStatistics *n = (*it);
+                if ((n->getPid() != n->gone) && (n->sizes() > l->sizes())) {
+                    pass = true;
+                    Pids.erase(it);
+                    Pids.insert(lt, n);
+                    it = lt;
+                    n = l;
+                }
+                lt = it;
+                l = n;
+            }
+        }
+    }
+}
+
 size_t UidStatistics::sizes(pid_t pid) {
-    size_t sizes = 0;
+    if (pid == pid_all) {
+        return sizes();
+    }
+
     PidStatisticsCollection::iterator it;
     for (it = begin(); it != end(); ++it) {
         PidStatistics *p = *it;
-        if ((pid == pid_all) || (pid == p->getPid())) {
-            sizes += p->sizes();
+        if (pid == p->getPid()) {
+            return p->sizes();
         }
     }
-    return sizes;
+    return 0;
 }
 
 size_t UidStatistics::elements(pid_t pid) {
-    size_t elements = 0;
+    if (pid == pid_all) {
+        return elements();
+    }
+
     PidStatisticsCollection::iterator it;
     for (it = begin(); it != end(); ++it) {
         PidStatistics *p = *it;
-        if ((pid == pid_all) || (pid == p->getPid())) {
-            elements += p->elements();
+        if (pid == p->getPid()) {
+            return p->elements();
         }
     }
-    return elements;
+    return 0;
 }
 
 size_t UidStatistics::sizesTotal(pid_t pid) {
@@ -266,6 +312,29 @@
     }
 }
 
+void LidStatistics::sort() {
+    for (bool pass = true; pass;) {
+        pass = false;
+        UidStatisticsCollection::iterator it = begin();
+        if (it != end()) {
+            UidStatisticsCollection::iterator lt = it;
+            UidStatistics *l = (*lt);
+            while (++it != end()) {
+                UidStatistics *n = (*it);
+                if (n->sizes() > l->sizes()) {
+                    pass = true;
+                    Uids.erase(it);
+                    Uids.insert(lt, n);
+                    it = lt;
+                    n = l;
+                }
+                lt = it;
+                l = n;
+            }
+        }
+    }
+}
+
 size_t LidStatistics::sizes(uid_t uid, pid_t pid) {
     size_t sizes = 0;
     UidStatisticsCollection::iterator it;
@@ -323,8 +392,8 @@
 
     dgram_qlen_statistics = false;
     for(unsigned short bucket = 0; dgram_qlen(bucket); ++bucket) {
-        mMinimum[bucket].tv_sec = (uint32_t)-1;
-        mMinimum[bucket].tv_nsec = 999999999UL;
+        mMinimum[bucket].tv_sec = mMinimum[bucket].tv_sec_max;
+        mMinimum[bucket].tv_nsec = mMinimum[bucket].tv_nsec_max;
     }
 }
 
@@ -370,7 +439,7 @@
 }
 
 unsigned long long LogStatistics::minimum(unsigned short bucket) {
-    if (mMinimum[bucket].tv_sec == LONG_MAX) {
+    if (mMinimum[bucket].tv_sec == mMinimum[bucket].tv_sec_max) {
         return 0;
     }
     return mMinimum[bucket].nsec();
@@ -455,13 +524,22 @@
     short spaces = 2;
 
     log_id_for_each(i) {
-        if (logMask & (1 << i)) {
-            oldLength = string.length();
-            if (spaces < 0) {
-                spaces = 0;
-            }
-            string.appendFormat("%*s%s", spaces, "", android_log_id_to_name(i));
-            spaces += spaces_total + oldLength - string.length();
+        if (!logMask & (1 << i)) {
+            continue;
+        }
+        oldLength = string.length();
+        if (spaces < 0) {
+            spaces = 0;
+        }
+        string.appendFormat("%*s%s", spaces, "", android_log_id_to_name(i));
+        spaces += spaces_total + oldLength - string.length();
+
+        LidStatistics &l = id(i);
+        l.sort();
+
+        UidStatisticsCollection::iterator iu;
+        for (iu = l.begin(); iu != l.end(); ++iu) {
+            (*iu)->sort();
         }
     }
 
@@ -597,8 +675,7 @@
                             sizes, sizesTotal);
 
             android::String8 pd("");
-            pd.appendFormat("%u%c", pid,
-                            (kill(pid, 0) && (errno != EPERM)) ? '?' : ' ');
+            pd.appendFormat("%u%c", pid, p->pidGone() ? '?' : ' ');
 
             string.appendFormat("\n%-7s%-*s %-7s%s",
                                 line ? "" : android_log_id_to_name(i),
@@ -703,14 +780,15 @@
             spaces = 0;
 
             uid_t u = up->getUid();
-            pid_t p = (*pt)->getPid();
+            PidStatistics *pp = *pt;
+            pid_t p = pp->getPid();
 
             intermediate = string.format(oneline
                                              ? ((p == PidStatistics::gone)
                                                  ? "%d/?"
-                                                 : "%d/%d")
+                                                 : "%d/%d%c")
                                              : "%d",
-                                         u, p);
+                                         u, p, pp->pidGone() ? '?' : '\0');
             string.appendFormat(first ? "\n%-12s" : "%-12s",
                                 intermediate.string());
             intermediate.clear();
@@ -747,8 +825,8 @@
             size_t gone_els = 0;
 
             for(; pt != up->end(); ++pt) {
-                PidStatistics *pp = *pt;
-                pid_t p = pp->getPid();
+                pp = *pt;
+                p = pp->getPid();
 
                 // If a PID no longer has any current logs, and is not
                 // active anymore, skip & report totals for gone.
@@ -760,7 +838,7 @@
                     continue;
                 }
                 els = pp->elements();
-                bool gone = kill(p, 0) && (errno != EPERM);
+                bool gone = pp->pidGone();
                 if (gone && (els == 0)) {
                     // ToDo: garbage collection: move this statistical bucket
                     //       from its current UID/PID to UID/? (races and
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
index 12c68d5..3733137 100644
--- a/logd/LogStatistics.h
+++ b/logd/LogStatistics.h
@@ -37,6 +37,7 @@
     size_t mElements;
 
     char *name;
+    bool mGone;
 
 public:
     static const pid_t gone = (pid_t) -1;
@@ -46,6 +47,7 @@
     ~PidStatistics();
 
     pid_t getPid() const { return pid; }
+    bool pidGone();
     char *getName() const { return name; }
     void setName(char *name);
 
@@ -70,6 +72,9 @@
 
     PidStatisticsCollection Pids;
 
+    size_t mSizes;
+    size_t mElements;
+
 public:
     UidStatistics(uid_t uid);
     ~UidStatistics();
@@ -81,11 +86,17 @@
 
     void add(unsigned short size, pid_t pid);
     void subtract(unsigned short size, pid_t pid);
+    void sort();
 
     static const pid_t pid_all = (pid_t) -1;
 
-    size_t sizes(pid_t pid = pid_all);
-    size_t elements(pid_t pid = pid_all);
+    // fast track current value
+    size_t sizes() const { return mSizes; };
+    size_t elements() const { return mElements; };
+
+    // statistical track
+    size_t sizes(pid_t pid);
+    size_t elements(pid_t pid);
 
     size_t sizesTotal(pid_t pid = pid_all);
     size_t elementsTotal(pid_t pid = pid_all);
@@ -108,6 +119,7 @@
 
     void add(unsigned short size, uid_t uid, pid_t pid);
     void subtract(unsigned short size, uid_t uid, pid_t pid);
+    void sort();
 
     static const pid_t pid_all = (pid_t) -1;
     static const uid_t uid_all = (uid_t) -1;
@@ -145,6 +157,7 @@
 
     void add(unsigned short size, log_id_t log_id, uid_t uid, pid_t pid);
     void subtract(unsigned short size, log_id_t log_id, uid_t uid, pid_t pid);
+    void sort();
 
     // fast track current value by id only
     size_t sizes(log_id_t id) const { return mSizes[id]; }
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
index c32ac2d..1a9a548 100644
--- a/logd/LogTimes.cpp
+++ b/logd/LogTimes.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <sys/prctl.h>
+
 #include "FlushCommand.h"
 #include "LogBuffer.h"
 #include "LogTimes.h"
@@ -107,6 +109,8 @@
 }
 
 void *LogTimeEntry::threadStart(void *obj) {
+    prctl(PR_SET_NAME, "logd.reader.per");
+
     LogTimeEntry *me = reinterpret_cast<LogTimeEntry *>(obj);
 
     pthread_cleanup_push(threadStop, obj);
diff --git a/logd/LogWhiteBlackList.cpp b/logd/LogWhiteBlackList.cpp
index f739865..e87b604 100644
--- a/logd/LogWhiteBlackList.cpp
+++ b/logd/LogWhiteBlackList.cpp
@@ -65,7 +65,7 @@
 }
 
 int PruneList::init(char *str) {
-    mWorstUidEnabled = true;
+    mWorstUidEnabled = false;
     PruneCollection::iterator it;
     for (it = mNice.begin(); it != mNice.end();) {
         delete (*it);
diff --git a/logd/README.property b/logd/README.property
index 15a49db..f4b3c3c 100644
--- a/logd/README.property
+++ b/logd/README.property
@@ -1,11 +1,25 @@
 The properties that logd responds to are:
 
 name                       type default  description
+logd.auditd                 bool  true   Enable selinux audit daemon
 logd.auditd.dmesg           bool  true   selinux audit messages duplicated and
                                          sent on to dmesg log
-logd.dgram_qlen.statistics  bool  false  Record dgram_qlen statistics. This
+logd.statistics.dgram_qlen  bool  false  Record dgram_qlen statistics. This
                                          represents a performance impact and
                                          is used to determine the platform's
                                          minimum domain socket network FIFO
                                          size (see source for details) based
-                                         on typical load (logcat -S)
+                                         on typical load (logcat -S to view)
+persist.logd.size          number 256K   default size of the buffer for all
+                                         log ids at initial startup, at runtime
+                                         use: logcat -b all -G <value>
+persist.logd.size.main     number 256K   Size of the buffer for the main log
+persist.logd.size.system   number 256K   Size of the buffer for the system log
+persist.logd.size.radio    number 256K   Size of the buffer for the radio log
+persist.logd.size.event    number 256K   Size of the buffer for the event log
+persist.logd.size.crash    number 256K   Size of the buffer for the crash log
+
+NB:
+- number support multipliers (K or M) for convenience. Range is limited
+  to between 64K and 256M for log buffer sizes. Individual logs override the
+  global default.
diff --git a/logd/event.logtags b/logd/event.logtags
new file mode 100644
index 0000000..a63f034
--- /dev/null
+++ b/logd/event.logtags
@@ -0,0 +1,36 @@
+# The entries in this file map a sparse set of log tag numbers to tag names.
+# This is installed on the device, in /system/etc, and parsed by logcat.
+#
+# Tag numbers are decimal integers, from 0 to 2^31.  (Let's leave the
+# negative values alone for now.)
+#
+# Tag names are one or more ASCII letters and numbers or underscores, i.e.
+# "[A-Z][a-z][0-9]_".  Do not include spaces or punctuation (the former
+# impacts log readability, the latter makes regex searches more annoying).
+#
+# Tag numbers and names are separated by whitespace.  Blank lines and lines
+# starting with '#' are ignored.
+#
+# Optionally, after the tag names can be put a description for the value(s)
+# of the tag. Description are in the format
+#    (<name>|data type[|data unit])
+# Multiple values are separated by commas.
+#
+# The data type is a number from the following values:
+# 1: int
+# 2: long
+# 3: string
+# 4: list
+#
+# The data unit is a number taken from the following list:
+# 1: Number of objects
+# 2: Number of bytes
+# 3: Number of milliseconds
+# 4: Number of allocations
+# 5: Id
+# 6: Percent
+# Default value for data of type int/long is 2 (bytes).
+#
+# TODO: generate ".java" and ".h" files with integer constants from this file.
+
+1003  auditd (avc|3)
diff --git a/logd/main.cpp b/logd/main.cpp
index 04eef4a..ece5a3a 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -107,16 +107,31 @@
     return 0;
 }
 
+// Property helper
+static bool property_get_bool(const char *key, bool def) {
+    char property[PROPERTY_VALUE_MAX];
+    property_get(key, property, "");
+
+    if (!strcasecmp(property, "true")) {
+        return true;
+    }
+    if (!strcasecmp(property, "false")) {
+        return false;
+    }
+
+    return def;
+}
+
 // Foreground waits for exit of the three main persistent threads that
 // are started here.  The three threads are created to manage UNIX
 // domain client sockets for writing, reading and controlling the user
 // space logger.  Additional transitory per-client threads are created
 // for each reader once they register.
 int main() {
+    bool auditd = property_get_bool("logd.auditd", true);
+
     int fdDmesg = -1;
-    char dmesg[PROPERTY_VALUE_MAX];
-    property_get("logd.auditd.dmesg", dmesg, "1");
-    if (atol(dmesg)) {
+    if (auditd && property_get_bool("logd.auditd.dmesg", true)) {
         fdDmesg = open("/dev/kmsg", O_WRONLY);
     }
 
@@ -135,9 +150,7 @@
 
     LogBuffer *logBuf = new LogBuffer(times);
 
-    char dgram_qlen_statistics[PROPERTY_VALUE_MAX];
-    property_get("logd.dgram_qlen.statistics", dgram_qlen_statistics, "");
-    if (atol(dgram_qlen_statistics)) {
+    if (property_get_bool("logd.statistics.dgram_qlen", false)) {
         logBuf->enableDgramQlenStatistics();
     }
 
@@ -171,11 +184,13 @@
     // initiated log messages. New log entries are added to LogBuffer
     // and LogReader is notified to send updates to connected clients.
 
-    // failure is an option ... messages are in dmesg (required by standard)
-    LogAudit *al = new LogAudit(logBuf, reader, fdDmesg);
-    if (al->startListener()) {
-        delete al;
-        close(fdDmesg);
+    if (auditd) {
+        // failure is an option ... messages are in dmesg (required by standard)
+        LogAudit *al = new LogAudit(logBuf, reader, fdDmesg);
+        if (al->startListener()) {
+            delete al;
+            close(fdDmesg);
+        }
     }
 
     pause();
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index 23e6146..5b51b1f 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -23,6 +23,7 @@
 #include <gtest/gtest.h>
 
 #include "cutils/sockets.h"
+#include "log/log.h"
 #include "log/logger.h"
 
 #define __unused __attribute__((__unused__))
@@ -96,8 +97,9 @@
     //
     // main: UID/PID Total size/num   Now          UID/PID[?]  Total
     // 0           7500306/304207     71608/3183   0/4225?     7454388/303656
+    //    <wrap>                                                     93432/1012
     // -or-
-    // 0/gone      7454388/303656
+    // 0/gone      7454388/303656     93432/1012
     //
     // basically if we see a *large* number of 0/????? entries
     unsigned long value;
@@ -126,6 +128,15 @@
                 value = value * 10ULL + *cp - '0';
                 ++cp;
             }
+            if (*cp != '/') {
+                value = 0;
+                continue;
+            }
+            while (isdigit(*++cp));
+            while (*cp == ' ') ++cp;
+            if (!isdigit(*cp)) {
+                value = 0;
+            }
         }
     } while ((value < 900000ULL) && *cp);
     return cp;
@@ -185,8 +196,6 @@
 
     cp = strstr(cp, "Minimum time between log events per dgram_qlen:");
 
-    char *log_events_per_span = cp;
-
     if (cp) {
         while (*cp && (*cp != '\n')) {
             ++cp;
@@ -451,7 +460,7 @@
             dump_log_msg("user", &msg, 3, -1);
         }
 
-        alarm(0);
+        alarm(old_alarm);
         sigaction(SIGALRM, &old_sigaction, NULL);
 
         close(fd);
@@ -624,7 +633,45 @@
 #endif
 
     ASSERT_TRUE(NULL != buf);
-    EXPECT_TRUE(find_benchmark_spam(buf) != NULL);
+
+    char *benchmark_statistics_found = find_benchmark_spam(buf);
+    ASSERT_TRUE(benchmark_statistics_found != NULL);
+
+    // Check how effective the SPAM filter is, parse out Now size.
+    //             Total               Now
+    // 0/4225?     7454388/303656      31488/755
+    //                                 ^-- benchmark_statistics_found
+
+    unsigned long nowSize = atol(benchmark_statistics_found);
 
     delete [] buf;
+
+    ASSERT_NE(0UL, nowSize);
+
+    int sock = socket_local_client("logd",
+                                   ANDROID_SOCKET_NAMESPACE_RESERVED,
+                                   SOCK_STREAM);
+    static const unsigned long expected_absolute_minimum_log_size = 65536UL;
+    unsigned long totalSize = expected_absolute_minimum_log_size;
+    if (sock >= 0) {
+        static const char getSize[] = {
+            'g', 'e', 't', 'L', 'o', 'g', 'S', 'i', 'z', 'e', ' ',
+            LOG_ID_MAIN + '0', '\0'
+        };
+        if (write(sock, getSize, sizeof(getSize)) > 0) {
+            char buffer[80];
+            memset(buffer, 0, sizeof(buffer));
+            read(sock, buffer, sizeof(buffer));
+            totalSize = atol(buffer);
+            if (totalSize < expected_absolute_minimum_log_size) {
+                totalSize = expected_absolute_minimum_log_size;
+            }
+        }
+        close(sock);
+    }
+    // logd allows excursions to 110% of total size
+    totalSize = (totalSize * 11 ) / 10;
+
+    // 50% threshold for SPAM filter (<20% typical, lots of engineering margin)
+    ASSERT_GT(totalSize, nowSize * 2);
 }
diff --git a/logwrapper/Android.mk b/logwrapper/Android.mk
index 917bf37..61b4659 100644
--- a/logwrapper/Android.mk
+++ b/logwrapper/Android.mk
@@ -11,6 +11,7 @@
 LOCAL_SHARED_LIBRARIES := libcutils liblog
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_CFLAGS := -Werror
 include $(BUILD_STATIC_LIBRARY)
 
 # ========================================================
@@ -22,6 +23,7 @@
 LOCAL_WHOLE_STATIC_LIBRARIES := liblogwrap
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_CFLAGS := -Werror
 include $(BUILD_SHARED_LIBRARY)
 
 # ========================================================
@@ -31,4 +33,5 @@
 LOCAL_SRC_FILES:= logwrapper.c
 LOCAL_MODULE := logwrapper
 LOCAL_STATIC_LIBRARIES := liblog liblogwrap libcutils
+LOCAL_CFLAGS := -Werror
 include $(BUILD_EXECUTABLE)
diff --git a/logwrapper/logwrap.c b/logwrapper/logwrap.c
index 4ca1db4..d47c9b5 100644
--- a/logwrapper/logwrap.c
+++ b/logwrapper/logwrap.c
@@ -104,8 +104,6 @@
 static int add_line_to_linear_buf(struct beginning_buf *b_buf,
                                    char *line, ssize_t line_len)
 {
-    size_t new_len;
-    char *new_buf;
     int full = 0;
 
     if ((line_len + b_buf->used_len) > b_buf->buf_size) {
@@ -124,7 +122,6 @@
 {
     ssize_t free_len;
     ssize_t needed_space;
-    char *new_buf;
     int cnt;
 
     if (e_buf->buf == NULL) {
@@ -192,7 +189,6 @@
 {
     char *line_start;
     char c;
-    int line_len;
     int i;
 
     line_start = buf;
diff --git a/mkbootimg/Android.mk b/mkbootimg/Android.mk
index 2a97c26..0c9b0c6 100644
--- a/mkbootimg/Android.mk
+++ b/mkbootimg/Android.mk
@@ -4,6 +4,7 @@
 
 LOCAL_SRC_FILES := mkbootimg.c
 LOCAL_STATIC_LIBRARIES := libmincrypt
+LOCAL_CFLAGS := -Werror
 
 LOCAL_MODULE := mkbootimg
 
diff --git a/mkbootimg/mkbootimg.c b/mkbootimg/mkbootimg.c
index d598f03..fc92b4d 100644
--- a/mkbootimg/mkbootimg.c
+++ b/mkbootimg/mkbootimg.c
@@ -77,7 +77,7 @@
 int write_padding(int fd, unsigned pagesize, unsigned itemsize)
 {
     unsigned pagemask = pagesize - 1;
-    unsigned count;
+    ssize_t count;
 
     if((itemsize & pagemask) == 0) {
         return 0;
@@ -108,7 +108,7 @@
     unsigned pagesize = 2048;
     int fd;
     SHA_CTX ctx;
-    uint8_t* sha;
+    const uint8_t* sha;
     unsigned base           = 0x10000000;
     unsigned kernel_offset  = 0x00008000;
     unsigned ramdisk_offset = 0x01000000;
@@ -189,7 +189,7 @@
         return usage();
     }
 
-    strcpy(hdr.name, board);
+    strcpy((char *) hdr.name, board);
 
     memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE);
 
@@ -255,15 +255,15 @@
     if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail;
     if(write_padding(fd, pagesize, sizeof(hdr))) goto fail;
 
-    if(write(fd, kernel_data, hdr.kernel_size) != hdr.kernel_size) goto fail;
+    if(write(fd, kernel_data, hdr.kernel_size) != (ssize_t) hdr.kernel_size) goto fail;
     if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail;
 
-    if(write(fd, ramdisk_data, hdr.ramdisk_size) != hdr.ramdisk_size) goto fail;
+    if(write(fd, ramdisk_data, hdr.ramdisk_size) != (ssize_t) hdr.ramdisk_size) goto fail;
     if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail;
 
     if(second_data) {
-        if(write(fd, second_data, hdr.second_size) != hdr.second_size) goto fail;
-        if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail;
+        if(write(fd, second_data, hdr.second_size) != (ssize_t) hdr.second_size) goto fail;
+        if(write_padding(fd, pagesize, hdr.second_size)) goto fail;
     }
 
     return 0;
diff --git a/netcfg/Android.mk b/netcfg/Android.mk
index 949f417..fc01a54 100644
--- a/netcfg/Android.mk
+++ b/netcfg/Android.mk
@@ -11,6 +11,7 @@
 #LOCAL_STATIC_LIBRARIES := libcutils libc
 
 LOCAL_SHARED_LIBRARIES := libc libnetutils
+LOCAL_CFLAGS := -Werror
 
 include $(BUILD_EXECUTABLE)
 endif
diff --git a/netcfg/netcfg.c b/netcfg/netcfg.c
index 3738f24..2308f37 100644
--- a/netcfg/netcfg.c
+++ b/netcfg/netcfg.c
@@ -1,5 +1,4 @@
-/* system/bin/netcfg/netcfg.c
-**
+/*
 ** Copyright 2006, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
@@ -15,18 +14,14 @@
 ** limitations under the License.
 */
 
-#include <stdio.h>
-#include <stdlib.h>
 #include <errno.h>
 #include <dirent.h>
 #include <netinet/ether.h>
 #include <netinet/if_ether.h>
-
-#include <netutils/ifc.h>
 #include <netutils/dhcp.h>
-
-static int verbose = 0;
-
+#include <netutils/ifc.h>
+#include <stdio.h>
+#include <stdlib.h>
 
 void die(const char *reason)
 {
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.environ.rc.in b/rootdir/init.environ.rc.in
index 927c33d..1f964e3 100644
--- a/rootdir/init.environ.rc.in
+++ b/rootdir/init.environ.rc.in
@@ -9,3 +9,4 @@
     export ASEC_MOUNTPOINT /mnt/asec
     export LOOP_MOUNTPOINT /mnt/obb
     export BOOTCLASSPATH %BOOTCLASSPATH%
+    export LD_PRELOAD libsigchain.so
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 55a516a..e3a3017 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -98,13 +98,19 @@
     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
     write /proc/sys/kernel/sched_rt_runtime_us 950000
     write /proc/sys/kernel/sched_rt_period_us 1000000
 
+    # reflect fwmark from incoming packets onto generated replies
+    write /proc/sys/net/ipv4/fwmark_reflect 1
+    write /proc/sys/net/ipv6/fwmark_reflect 1
+
+    # set fwmark on accepted sockets
+    write /proc/sys/net/ipv4/tcp_fwmark_accept 1
+
 # Create cgroup mount points for process groups
     mkdir /dev/cpuctl
     mount cgroup none /dev/cpuctl cpu
@@ -144,6 +150,11 @@
 # checker programs.
     mkdir /dev/fscklogs 0770 root system
 
+# pstore/ramoops previous console log
+    mount pstore pstore /sys/fs/pstore
+    chown system log /sys/fs/pstore/console-ramoops
+    chmod 0440 /sys/fs/pstore/console-ramoops
+
 on post-fs
     # once everything is setup, no need to modify /
     mount rootfs rootfs / ro remount
@@ -220,6 +231,7 @@
     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
@@ -382,6 +394,9 @@
     setprop net.tcp.buffersize.gprs     4092,8760,48000,4096,8760,48000
     setprop net.tcp.buffersize.evdo     4094,87380,262144,4096,16384,262144
 
+# Define default initial receive window size in segments.
+    setprop net.tcp.default_init_rwnd 60
+
     class_start core
     class_start main
 
@@ -414,9 +429,15 @@
 on property:sys.powerctl=*
     powerctl ${sys.powerctl}
 
-# system server cannot write to /proc/sys files, so proxy it through init
+# system server cannot write to /proc/sys files,
+# and chown/chmod does not work for /proc/sys/ entries.
+# So proxy writes through init.
 on property:sys.sysctl.extra_free_kbytes=*
     write /proc/sys/vm/extra_free_kbytes ${sys.sysctl.extra_free_kbytes}
+# "tcp_default_init_rwnd" Is too long!
+on property:sys.sysctl.tcp_def_init_rwnd=*
+    write /proc/sys/net/ipv4/tcp_default_init_rwnd ${sys.sysctl.tcp_def_init_rwnd}
+
 
 ## Daemon processes to be run by init.
 ##
@@ -485,6 +506,7 @@
     socket netd stream 0660 root system
     socket dnsproxyd stream 0660 root inet
     socket mdns stream 0660 root system
+    socket fwmarkd stream 0660 root inet
 
 service debuggerd /system/bin/debuggerd
     class main
diff --git a/rootdir/init.zygote32_64.rc b/rootdir/init.zygote32_64.rc
index 3d60a31..68c0668 100644
--- a/rootdir/init.zygote32_64.rc
+++ b/rootdir/init.zygote32_64.rc
@@ -1,4 +1,4 @@
-service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
+service zygote /system/bin/app_process32 -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
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/rootdir/ueventd.rc b/rootdir/ueventd.rc
index b8fe716..eff24c3 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -91,3 +91,5 @@
 /sys/devices/virtual/input/input*   enable      0660  root   input
 /sys/devices/virtual/input/input*   poll_delay  0660  root   input
 /sys/devices/virtual/usb_composite/*   enable      0664  root   system
+/sys/devices/system/cpu/cpu*   cpufreq/scaling_max_freq   0664  system system
+/sys/devices/system/cpu/cpu*   cpufreq/scaling_min_freq   0664  system system
diff --git a/run-as/Android.mk b/run-as/Android.mk
index a8f2885..3774acc 100644
--- a/run-as/Android.mk
+++ b/run-as/Android.mk
@@ -1,10 +1,12 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= run-as.c package.c
+LOCAL_SRC_FILES := run-as.c package.c
 
 LOCAL_SHARED_LIBRARIES := libselinux
 
-LOCAL_MODULE:= run-as
+LOCAL_MODULE := run-as
+
+LOCAL_CFLAGS := -Werror
 
 include $(BUILD_EXECUTABLE)
diff --git a/run-as/package.c b/run-as/package.c
index 901e9e3..4f8f3a7 100644
--- a/run-as/package.c
+++ b/run-as/package.c
@@ -128,7 +128,9 @@
     }
 
     /* Memory-map the file now */
-    address = TEMP_FAILURE_RETRY(mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0));
+    do {
+        address = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);
+    } while (address == MAP_FAILED && errno == EINTR);
     if (address == MAP_FAILED) {
         address = NULL;
         goto EXIT;
@@ -408,10 +410,6 @@
         value = -1;
     }
     return value;
-
-BAD:
-    *pp = p;
-    return -1;
 }
 
 /* Read the system's package database and extract information about
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/sdcard/fuse.h b/sdcard/fuse.h
deleted file mode 100644
index 3138da9..0000000
--- a/sdcard/fuse.h
+++ /dev/null
@@ -1,578 +0,0 @@
-/*
-    FUSE: Filesystem in Userspace
-    Copyright (C) 2001-2008  Miklos Szeredi <miklos@szeredi.hu>
-
-    This program can be distributed under the terms of the GNU GPL.
-    See the file COPYING.
-*/
-
-/*
- * from the libfuse FAQ (and consistent with the Linux Kernel license):
- *
- * Under what conditions may I distribute a filesystem that uses the
- * raw kernel interface of FUSE?
- *
- * There are no restrictions whatsoever for using the raw kernel interface. 
- *
- */
-
-/*
- * This file defines the kernel interface of FUSE
- *
- * Protocol changelog:
- *
- * 7.9:
- *  - new fuse_getattr_in input argument of GETATTR
- *  - add lk_flags in fuse_lk_in
- *  - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
- *  - add blksize field to fuse_attr
- *  - add file flags field to fuse_read_in and fuse_write_in
- *
- * 7.10
- *  - add nonseekable open flag
- *
- * 7.11
- *  - add IOCTL message
- *  - add unsolicited notification support
- *  - add POLL message and NOTIFY_POLL notification
- *
- * 7.12
- *  - add umask flag to input argument of open, mknod and mkdir
- *  - add notification messages for invalidation of inodes and
- *    directory entries
- *
- * 7.13
- *  - make max number of background requests and congestion threshold
- *    tunables
- */
-
-#ifndef _LINUX_FUSE_H
-#define _LINUX_FUSE_H
-
-#include <linux/types.h>
-
-/*
- * Version negotiation:
- *
- * Both the kernel and userspace send the version they support in the
- * INIT request and reply respectively.
- *
- * If the major versions match then both shall use the smallest
- * of the two minor versions for communication.
- *
- * If the kernel supports a larger major version, then userspace shall
- * reply with the major version it supports, ignore the rest of the
- * INIT message and expect a new INIT message from the kernel with a
- * matching major version.
- *
- * If the library supports a larger major version, then it shall fall
- * back to the major protocol version sent by the kernel for
- * communication and reply with that major version (and an arbitrary
- * supported minor version).
- */
-
-/** Version number of this interface */
-#define FUSE_KERNEL_VERSION 7
-
-/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 13
-
-/** The node ID of the root inode */
-#define FUSE_ROOT_ID 1
-
-/* Make sure all structures are padded to 64bit boundary, so 32bit
-   userspace works under 64bit kernels */
-
-struct fuse_attr {
-	__u64	ino;
-	__u64	size;
-	__u64	blocks;
-	__u64	atime;
-	__u64	mtime;
-	__u64	ctime;
-	__u32	atimensec;
-	__u32	mtimensec;
-	__u32	ctimensec;
-	__u32	mode;
-	__u32	nlink;
-	__u32	uid;
-	__u32	gid;
-	__u32	rdev;
-	__u32	blksize;
-	__u32	padding;
-};
-
-struct fuse_kstatfs {
-	__u64	blocks;
-	__u64	bfree;
-	__u64	bavail;
-	__u64	files;
-	__u64	ffree;
-	__u32	bsize;
-	__u32	namelen;
-	__u32	frsize;
-	__u32	padding;
-	__u32	spare[6];
-};
-
-struct fuse_file_lock {
-	__u64	start;
-	__u64	end;
-	__u32	type;
-	__u32	pid; /* tgid */
-};
-
-/**
- * Bitmasks for fuse_setattr_in.valid
- */
-#define FATTR_MODE	(1 << 0)
-#define FATTR_UID	(1 << 1)
-#define FATTR_GID	(1 << 2)
-#define FATTR_SIZE	(1 << 3)
-#define FATTR_ATIME	(1 << 4)
-#define FATTR_MTIME	(1 << 5)
-#define FATTR_FH	(1 << 6)
-#define FATTR_ATIME_NOW	(1 << 7)
-#define FATTR_MTIME_NOW	(1 << 8)
-#define FATTR_LOCKOWNER	(1 << 9)
-
-/**
- * Flags returned by the OPEN request
- *
- * FOPEN_DIRECT_IO: bypass page cache for this open file
- * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
- * FOPEN_NONSEEKABLE: the file is not seekable
- */
-#define FOPEN_DIRECT_IO		(1 << 0)
-#define FOPEN_KEEP_CACHE	(1 << 1)
-#define FOPEN_NONSEEKABLE	(1 << 2)
-
-/**
- * INIT request/reply flags
- *
- * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
- * FUSE_DONT_MASK: don't apply umask to file mode on create operations
- */
-#define FUSE_ASYNC_READ		(1 << 0)
-#define FUSE_POSIX_LOCKS	(1 << 1)
-#define FUSE_FILE_OPS		(1 << 2)
-#define FUSE_ATOMIC_O_TRUNC	(1 << 3)
-#define FUSE_EXPORT_SUPPORT	(1 << 4)
-#define FUSE_BIG_WRITES		(1 << 5)
-#define FUSE_DONT_MASK		(1 << 6)
-
-/**
- * CUSE INIT request/reply flags
- *
- * CUSE_UNRESTRICTED_IOCTL:  use unrestricted ioctl
- */
-#define CUSE_UNRESTRICTED_IOCTL	(1 << 0)
-
-/**
- * Release flags
- */
-#define FUSE_RELEASE_FLUSH	(1 << 0)
-
-/**
- * Getattr flags
- */
-#define FUSE_GETATTR_FH		(1 << 0)
-
-/**
- * Lock flags
- */
-#define FUSE_LK_FLOCK		(1 << 0)
-
-/**
- * WRITE flags
- *
- * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
- * FUSE_WRITE_LOCKOWNER: lock_owner field is valid
- */
-#define FUSE_WRITE_CACHE	(1 << 0)
-#define FUSE_WRITE_LOCKOWNER	(1 << 1)
-
-/**
- * Read flags
- */
-#define FUSE_READ_LOCKOWNER	(1 << 1)
-
-/**
- * Ioctl flags
- *
- * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
- * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
- * FUSE_IOCTL_RETRY: retry with new iovecs
- *
- * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
- */
-#define FUSE_IOCTL_COMPAT	(1 << 0)
-#define FUSE_IOCTL_UNRESTRICTED	(1 << 1)
-#define FUSE_IOCTL_RETRY	(1 << 2)
-
-#define FUSE_IOCTL_MAX_IOV	256
-
-/**
- * Poll flags
- *
- * FUSE_POLL_SCHEDULE_NOTIFY: request poll notify
- */
-#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0)
-
-enum fuse_opcode {
-	FUSE_LOOKUP	   = 1,
-	FUSE_FORGET	   = 2,  /* no reply */
-	FUSE_GETATTR	   = 3,
-	FUSE_SETATTR	   = 4,
-	FUSE_READLINK	   = 5,
-	FUSE_SYMLINK	   = 6,
-	FUSE_MKNOD	   = 8,
-	FUSE_MKDIR	   = 9,
-	FUSE_UNLINK	   = 10,
-	FUSE_RMDIR	   = 11,
-	FUSE_RENAME	   = 12,
-	FUSE_LINK	   = 13,
-	FUSE_OPEN	   = 14,
-	FUSE_READ	   = 15,
-	FUSE_WRITE	   = 16,
-	FUSE_STATFS	   = 17,
-	FUSE_RELEASE       = 18,
-	FUSE_FSYNC         = 20,
-	FUSE_SETXATTR      = 21,
-	FUSE_GETXATTR      = 22,
-	FUSE_LISTXATTR     = 23,
-	FUSE_REMOVEXATTR   = 24,
-	FUSE_FLUSH         = 25,
-	FUSE_INIT          = 26,
-	FUSE_OPENDIR       = 27,
-	FUSE_READDIR       = 28,
-	FUSE_RELEASEDIR    = 29,
-	FUSE_FSYNCDIR      = 30,
-	FUSE_GETLK         = 31,
-	FUSE_SETLK         = 32,
-	FUSE_SETLKW        = 33,
-	FUSE_ACCESS        = 34,
-	FUSE_CREATE        = 35,
-	FUSE_INTERRUPT     = 36,
-	FUSE_BMAP          = 37,
-	FUSE_DESTROY       = 38,
-	FUSE_IOCTL         = 39,
-	FUSE_POLL          = 40,
-
-	/* CUSE specific operations */
-	CUSE_INIT          = 4096,
-};
-
-enum fuse_notify_code {
-	FUSE_NOTIFY_POLL   = 1,
-	FUSE_NOTIFY_INVAL_INODE = 2,
-	FUSE_NOTIFY_INVAL_ENTRY = 3,
-	FUSE_NOTIFY_CODE_MAX,
-};
-
-/* The read buffer is required to be at least 8k, but may be much larger */
-#define FUSE_MIN_READ_BUFFER 8192
-
-#define FUSE_COMPAT_ENTRY_OUT_SIZE 120
-
-struct fuse_entry_out {
-	__u64	nodeid;		/* Inode ID */
-	__u64	generation;	/* Inode generation: nodeid:gen must
-				   be unique for the fs's lifetime */
-	__u64	entry_valid;	/* Cache timeout for the name */
-	__u64	attr_valid;	/* Cache timeout for the attributes */
-	__u32	entry_valid_nsec;
-	__u32	attr_valid_nsec;
-	struct fuse_attr attr;
-};
-
-struct fuse_forget_in {
-	__u64	nlookup;
-};
-
-struct fuse_getattr_in {
-	__u32	getattr_flags;
-	__u32	dummy;
-	__u64	fh;
-};
-
-#define FUSE_COMPAT_ATTR_OUT_SIZE 96
-
-struct fuse_attr_out {
-	__u64	attr_valid;	/* Cache timeout for the attributes */
-	__u32	attr_valid_nsec;
-	__u32	dummy;
-	struct fuse_attr attr;
-};
-
-#define FUSE_COMPAT_MKNOD_IN_SIZE 8
-
-struct fuse_mknod_in {
-	__u32	mode;
-	__u32	rdev;
-	__u32	umask;
-	__u32	padding;
-};
-
-struct fuse_mkdir_in {
-	__u32	mode;
-	__u32	umask;
-};
-
-struct fuse_rename_in {
-	__u64	newdir;
-};
-
-struct fuse_link_in {
-	__u64	oldnodeid;
-};
-
-struct fuse_setattr_in {
-	__u32	valid;
-	__u32	padding;
-	__u64	fh;
-	__u64	size;
-	__u64	lock_owner;
-	__u64	atime;
-	__u64	mtime;
-	__u64	unused2;
-	__u32	atimensec;
-	__u32	mtimensec;
-	__u32	unused3;
-	__u32	mode;
-	__u32	unused4;
-	__u32	uid;
-	__u32	gid;
-	__u32	unused5;
-};
-
-struct fuse_open_in {
-	__u32	flags;
-	__u32	unused;
-};
-
-struct fuse_create_in {
-	__u32	flags;
-	__u32	mode;
-	__u32	umask;
-	__u32	padding;
-};
-
-struct fuse_open_out {
-	__u64	fh;
-	__u32	open_flags;
-	__u32	padding;
-};
-
-struct fuse_release_in {
-	__u64	fh;
-	__u32	flags;
-	__u32	release_flags;
-	__u64	lock_owner;
-};
-
-struct fuse_flush_in {
-	__u64	fh;
-	__u32	unused;
-	__u32	padding;
-	__u64	lock_owner;
-};
-
-struct fuse_read_in {
-	__u64	fh;
-	__u64	offset;
-	__u32	size;
-	__u32	read_flags;
-	__u64	lock_owner;
-	__u32	flags;
-	__u32	padding;
-};
-
-#define FUSE_COMPAT_WRITE_IN_SIZE 24
-
-struct fuse_write_in {
-	__u64	fh;
-	__u64	offset;
-	__u32	size;
-	__u32	write_flags;
-	__u64	lock_owner;
-	__u32	flags;
-	__u32	padding;
-};
-
-struct fuse_write_out {
-	__u32	size;
-	__u32	padding;
-};
-
-#define FUSE_COMPAT_STATFS_SIZE 48
-
-struct fuse_statfs_out {
-	struct fuse_kstatfs st;
-};
-
-struct fuse_fsync_in {
-	__u64	fh;
-	__u32	fsync_flags;
-	__u32	padding;
-};
-
-struct fuse_setxattr_in {
-	__u32	size;
-	__u32	flags;
-};
-
-struct fuse_getxattr_in {
-	__u32	size;
-	__u32	padding;
-};
-
-struct fuse_getxattr_out {
-	__u32	size;
-	__u32	padding;
-};
-
-struct fuse_lk_in {
-	__u64	fh;
-	__u64	owner;
-	struct fuse_file_lock lk;
-	__u32	lk_flags;
-	__u32	padding;
-};
-
-struct fuse_lk_out {
-	struct fuse_file_lock lk;
-};
-
-struct fuse_access_in {
-	__u32	mask;
-	__u32	padding;
-};
-
-struct fuse_init_in {
-	__u32	major;
-	__u32	minor;
-	__u32	max_readahead;
-	__u32	flags;
-};
-
-struct fuse_init_out {
-	__u32	major;
-	__u32	minor;
-	__u32	max_readahead;
-	__u32	flags;
-	__u16   max_background;
-	__u16   congestion_threshold;
-	__u32	max_write;
-};
-
-#define CUSE_INIT_INFO_MAX 4096
-
-struct cuse_init_in {
-	__u32	major;
-	__u32	minor;
-	__u32	unused;
-	__u32	flags;
-};
-
-struct cuse_init_out {
-	__u32	major;
-	__u32	minor;
-	__u32	unused;
-	__u32	flags;
-	__u32	max_read;
-	__u32	max_write;
-	__u32	dev_major;		/* chardev major */
-	__u32	dev_minor;		/* chardev minor */
-	__u32	spare[10];
-};
-
-struct fuse_interrupt_in {
-	__u64	unique;
-};
-
-struct fuse_bmap_in {
-	__u64	block;
-	__u32	blocksize;
-	__u32	padding;
-};
-
-struct fuse_bmap_out {
-	__u64	block;
-};
-
-struct fuse_ioctl_in {
-	__u64	fh;
-	__u32	flags;
-	__u32	cmd;
-	__u64	arg;
-	__u32	in_size;
-	__u32	out_size;
-};
-
-struct fuse_ioctl_out {
-	__s32	result;
-	__u32	flags;
-	__u32	in_iovs;
-	__u32	out_iovs;
-};
-
-struct fuse_poll_in {
-	__u64	fh;
-	__u64	kh;
-	__u32	flags;
-	__u32   padding;
-};
-
-struct fuse_poll_out {
-	__u32	revents;
-	__u32	padding;
-};
-
-struct fuse_notify_poll_wakeup_out {
-	__u64	kh;
-};
-
-struct fuse_in_header {
-	__u32	len;
-	__u32	opcode;
-	__u64	unique;
-	__u64	nodeid;
-	__u32	uid;
-	__u32	gid;
-	__u32	pid;
-	__u32	padding;
-};
-
-struct fuse_out_header {
-	__u32	len;
-	__s32	error;
-	__u64	unique;
-};
-
-struct fuse_dirent {
-	__u64	ino;
-	__u64	off;
-	__u32	namelen;
-	__u32	type;
-	char name[0];
-};
-
-#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
-#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
-#define FUSE_DIRENT_SIZE(d) \
-	FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
-
-struct fuse_notify_inval_inode_out {
-	__u64	ino;
-	__s64	off;
-	__s64	len;
-};
-
-struct fuse_notify_inval_entry_out {
-	__u64	parent;
-	__u32	namelen;
-	__u32	padding;
-};
-
-#endif /* _LINUX_FUSE_H */
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 6a9c2eb..7baad63 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -14,23 +14,24 @@
  * limitations under the License.
  */
 
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <linux/fuse.h>
+#include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
+#include <sys/inotify.h>
 #include <sys/mount.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/statfs.h>
-#include <sys/uio.h>
-#include <dirent.h>
-#include <limits.h>
-#include <ctype.h>
-#include <pthread.h>
 #include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/inotify.h>
+#include <sys/uio.h>
+#include <unistd.h>
 
 #include <cutils/fs.h>
 #include <cutils/hashmap.h>
@@ -38,15 +39,13 @@
 
 #include <private/android_filesystem_config.h>
 
-#include "fuse.h"
-
 /* README
  *
  * What is this?
- * 
+ *
  * sdcard is a program that uses FUSE to emulate FAT-on-sdcard style
- * directory permissions (all files are given fixed owner, group, and 
- * permissions at creation, owner, group, and permissions are not 
+ * directory permissions (all files are given fixed owner, group, and
+ * permissions at creation, owner, group, and permissions are not
  * changeable, symlinks and hardlinks are not createable, etc.
  *
  * See usage() for command line options.
@@ -1245,7 +1244,7 @@
     struct handle *h = id_to_ptr(req->fh);
     int res;
     __u8 aligned_buffer[req->size] __attribute__((__aligned__(PAGESIZE)));
-    
+
     if (req->flags & O_DIRECT) {
         memcpy(aligned_buffer, buffer, req->size);
         buffer = (const __u8*) aligned_buffer;
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index 5383b83..fddf0a9 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -96,7 +96,7 @@
 
 LOCAL_CFLAGS += \
     -std=gnu99 \
-    -Wno-unused-parameter \
+    -Werror -Wno-unused-parameter \
     -include bsd-compatibility.h \
 
 LOCAL_SHARED_LIBRARIES := \
diff --git a/toolbox/cp/cp.c b/toolbox/cp/cp.c
index bd3c70e..e666453 100644
--- a/toolbox/cp/cp.c
+++ b/toolbox/cp/cp.c
@@ -95,12 +95,14 @@
 
 static int copy(char *[], enum op, int);
 
+#ifndef ANDROID
 static void
 progress(int sig __unused)
 {
 
 	pinfo++;
 }
+#endif
 
 int
 cp_main(int argc, char *argv[])
diff --git a/toolbox/cp/utils.c b/toolbox/cp/utils.c
index b682bbe..9d0390f 100644
--- a/toolbox/cp/utils.c
+++ b/toolbox/cp/utils.c
@@ -380,10 +380,11 @@
 int
 setfile(struct stat *fs, int fd)
 {
-	int rval, islink;
+	int rval = 0;
+#ifndef ANDROID
+	int islink = S_ISLNK(fs->st_mode);
+#endif
 
-	rval = 0;
-	islink = S_ISLNK(fs->st_mode);
 	fs->st_mode &= S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
 
 	/*
@@ -401,13 +402,13 @@
 		fs->st_mode &= ~(S_ISUID | S_ISGID);
 	}
 #ifdef ANDROID
-    if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) {
+        if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) {
 #else
-    if (fd ? fchmod(fd, fs->st_mode) : lchmod(to.p_path, fs->st_mode)) {
+        if (fd ? fchmod(fd, fs->st_mode) : lchmod(to.p_path, fs->st_mode)) {
 #endif
-        warn("chmod: %s", to.p_path);
-        rval = 1;
-    }
+                warn("chmod: %s", to.p_path);
+                rval = 1;
+        }
 
 #ifndef ANDROID
 	if (!islink && !Nflag) {
diff --git a/toolbox/date.c b/toolbox/date.c
index aa3b72e..70ce1d5 100644
--- a/toolbox/date.c
+++ b/toolbox/date.c
@@ -140,14 +140,12 @@
 
 int date_main(int argc, char *argv[])
 {
-	int c;
+    int c;
     int res;
-	struct tm tm;
-	time_t t;
-	struct timeval tv;
-    struct timespec ts;
-	char strbuf[260];
-    int fd;
+    struct tm tm;
+    time_t t;
+    struct timeval tv;
+    char strbuf[260];
 
     int useutc = 0;
 
@@ -177,7 +175,6 @@
 
     int hasfmt = argc == optind + 1 && argv[optind][0] == '+';
     if(optind == argc || hasfmt) {
-        char buf[2000];
         time(&t);
         if (useutc) {
             gmtime_r(&t, &tm);
diff --git a/toolbox/dd.c b/toolbox/dd.c
index 6b61ffb..408a496 100644
--- a/toolbox/dd.c
+++ b/toolbox/dd.c
@@ -356,7 +356,7 @@
 			++st.in_full;
 
 		/* Handle full input blocks. */
-		} else if (n == in.dbsz) {
+		} else if (n == (int64_t)in.dbsz) {
 			in.dbcnt += in.dbrcnt = n;
 			++st.in_full;
 
@@ -521,7 +521,7 @@
 			outp += nw;
 			st.bytes += nw;
 			if (nw == n) {
-				if (n != out.dbsz)
+				if (n != (int64_t)out.dbsz)
 					++st.out_part;
 				else
 					++st.out_full;
@@ -649,8 +649,8 @@
 void
 pos_out(void)
 {
-//	struct mtop t_op;
-	int cnt, n;
+/*	struct mtop t_op;        */
+	int64_t cnt, n;
 
 	/*
 	 * If not a tape, try seeking on the file.  Seeking on a pipe is
@@ -681,7 +681,7 @@
 	}
 
 	/* Read it. */
-	for (cnt = 0; cnt < out.offset; ++cnt) {
+	for (cnt = 0; cnt < (int64_t)out.offset; ++cnt) {
 		if ((n = read(out.fd, out.db, out.dbsz)) > 0)
 			continue;
 
@@ -705,8 +705,8 @@
 			/* NOTREACHED */
 		}
 
-		while (cnt++ < out.offset)
-			if ((n = bwrite(out.fd, out.db, out.dbsz)) != out.dbsz) {
+		while (cnt++ < (int64_t)out.offset)
+			if ((n = bwrite(out.fd, out.db, out.dbsz)) != (int64_t)out.dbsz) {
 				fprintf(stderr, "%s: cannot position "
 					"by writing: %s\n",
 					out.name, strerror(errno));
@@ -1153,7 +1153,7 @@
 	    ((const struct arg *)b)->name));
 }
 
-static long long strsuftoll(const char* name, const char* arg, int def, unsigned int max)
+static long long strsuftoll(const char* name, const char* arg, int def, unsigned long long max)
 {
 	long long result;
 	
@@ -1180,7 +1180,7 @@
 f_count(char *arg)
 {
 
-	cpy_cnt = strsuftoll("block count", arg, 0, LLONG_MAX);
+	cpy_cnt = (uint64_t)strsuftoll("block count", arg, 0, 0xFFFFFFFFFFFFFFFFULL);
 	if (!cpy_cnt)
 		terminate(0);
 }
@@ -1228,14 +1228,14 @@
 f_seek(char *arg)
 {
 
-	out.offset = strsuftoll("seek blocks", arg, 0, LLONG_MAX);
+	out.offset = (uint64_t)strsuftoll("seek blocks", arg, 0, 0xFFFFFFFFFFFFFFFFULL);
 }
 
 static void
 f_skip(char *arg)
 {
 
-	in.offset = strsuftoll("skip blocks", arg, 0, LLONG_MAX);
+	in.offset = (uint64_t)strsuftoll("skip blocks", arg, 0, 0xFFFFFFFFFFFFFFFFULL);
 }
 
 static void
diff --git a/toolbox/du.c b/toolbox/du.c
index fc7c943..c8beba5 100644
--- a/toolbox/du.c
+++ b/toolbox/du.c
@@ -76,7 +76,7 @@
 	int64_t totalblocks;
 	int ftsoptions, listfiles;
 	int depth;
-	int Hflag, Lflag, aflag, ch, cflag, dflag, gkmflag, nflag, rval, sflag;
+	int Hflag, Lflag, aflag, ch, cflag, dflag, gkmflag, rval, sflag;
 	const char *noargv[2];
 
 	Hflag = Lflag = aflag = cflag = dflag = gkmflag = sflag = 0;
diff --git a/toolbox/getevent.c b/toolbox/getevent.c
index ed381f5..c2256ff 100644
--- a/toolbox/getevent.c
+++ b/toolbox/getevent.c
@@ -492,13 +492,11 @@
     int c;
     int i;
     int res;
-    int pollres;
     int get_time = 0;
     int print_device = 0;
     char *newline = "\n";
     uint16_t get_switch = 0;
     struct input_event event;
-    int version;
     int print_flags = 0;
     int print_flags_set = 0;
     int dont_block = -1;
@@ -629,7 +627,8 @@
         return 0;
 
     while(1) {
-        pollres = poll(ufds, nfds, -1);
+        //int pollres =
+        poll(ufds, nfds, -1);
         //printf("poll %d, returned %d\n", nfds, pollres);
         if(ufds[0].revents & POLLIN) {
             read_notify(device_path, ufds[0].fd, print_flags);
diff --git a/toolbox/getevent.h b/toolbox/getevent.h
index 2b76209..0482d04 100644
--- a/toolbox/getevent.h
+++ b/toolbox/getevent.h
@@ -652,6 +652,7 @@
         LABEL_END,
 };
 
+#if 0
 static struct label id_labels[] = {
         LABEL(ID_BUS),
         LABEL(ID_VENDOR),
@@ -682,6 +683,7 @@
         LABEL(BUS_SPI),
         LABEL_END,
 };
+#endif
 
 static struct label mt_tool_labels[] = {
         LABEL(MT_TOOL_FINGER),
diff --git a/toolbox/getprop.c b/toolbox/getprop.c
index c001fda..dcc0ea0 100644
--- a/toolbox/getprop.c
+++ b/toolbox/getprop.c
@@ -3,7 +3,6 @@
 
 #include <cutils/properties.h>
 
-#include <sys/system_properties.h>
 #include "dynarray.h"
 
 static void record_prop(const char* key, const char* name, void* opaque)
@@ -31,12 +30,8 @@
     strlist_done(list);
 }
 
-int __system_property_wait(prop_info *pi);
-
 int getprop_main(int argc, char *argv[])
 {
-    int n = 0;
-
     if (argc == 1) {
         list_properties();
     } else {
diff --git a/toolbox/grep/file.c b/toolbox/grep/file.c
index 86b7658..d28dff5 100644
--- a/toolbox/grep/file.c
+++ b/toolbox/grep/file.c
@@ -78,7 +78,9 @@
 grep_refill(struct file *f)
 {
 	ssize_t nr;
+#ifndef ANDROID
 	int bzerr;
+#endif
 
 	bufpos = buffer;
 	bufrem = 0;
diff --git a/toolbox/grep/grep.c b/toolbox/grep/grep.c
index 5a4fa0c..7b2c487 100644
--- a/toolbox/grep/grep.c
+++ b/toolbox/grep/grep.c
@@ -403,7 +403,7 @@
 				Aflag = 0;
 			else if (Aflag > LLONG_MAX / 10) {
 				errno = ERANGE;
-				err(2, NULL);
+				err(2, "%llu", Aflag);
 			}
 			Aflag = Bflag = (Aflag * 10) + (c - '0');
 			break;
@@ -420,10 +420,10 @@
 			l = strtoull(optarg, &ep, 10);
 			if (((errno == ERANGE) && (l == ULLONG_MAX)) ||
 			    ((errno == EINVAL) && (l == 0)))
-				err(2, NULL);
+				err(2, "strtoull");
 			else if (ep[0] != '\0') {
 				errno = EINVAL;
-				err(2, NULL);
+				err(2, "empty");
 			}
 			if (c == 'A')
 				Aflag = l;
@@ -509,10 +509,10 @@
 			mcount = strtoull(optarg, &ep, 10);
 			if (((errno == ERANGE) && (mcount == ULLONG_MAX)) ||
 			    ((errno == EINVAL) && (mcount == 0)))
-				err(2, NULL);
+				err(2, "strtoull");
 			else if (ep[0] != '\0') {
 				errno = EINVAL;
-				err(2, NULL);
+				err(2, "empty");
 			}
 			break;
 		case 'n':
diff --git a/toolbox/grep/util.c b/toolbox/grep/util.c
index 497db06..5712fee 100644
--- a/toolbox/grep/util.c
+++ b/toolbox/grep/util.c
@@ -273,7 +273,7 @@
 	return (c);
 }
 
-#define iswword(x)	(iswalnum((x)) || (x) == L'_')
+#define iswword(x)	(iswalnum((wint_t)(x)) || (x) == L'_')
 
 /*
  * Processes a line comparing it with the specified patterns.  Each pattern
@@ -323,7 +323,7 @@
 				continue;
 			/* Check for whole word match */
 			if (fg_pattern[i].word && pmatch.rm_so != 0) {
-				wint_t wbegin, wend;
+				wchar_t wbegin, wend;
 
 				wbegin = wend = L' ';
 				if (pmatch.rm_so != 0 &&
diff --git a/toolbox/hd.c b/toolbox/hd.c
index 0d2f96a..7c9998e 100644
--- a/toolbox/hd.c
+++ b/toolbox/hd.c
@@ -14,7 +14,6 @@
 	unsigned char buf[4096];
     int res;
 	int read_len;
-	int rv = 0;
 	int i;
 	int filepos = 0;
 	int sum;
diff --git a/toolbox/insmod.c b/toolbox/insmod.c
index fb1448b..d252433 100644
--- a/toolbox/insmod.c
+++ b/toolbox/insmod.c
@@ -73,7 +73,7 @@
 		char *ptr = opts;
 
 		for (i = 2; (i < argc) && (ptr < end); i++) {
-			len = MIN(strlen(argv[i]), end - ptr);
+			len = MIN(strlen(argv[i]), (size_t)(end - ptr));
 			memcpy(ptr, argv[i], len);
 			ptr += len;
 			*ptr++ = ' ';
diff --git a/toolbox/ioctl.c b/toolbox/ioctl.c
index fb555d2..17fabff 100644
--- a/toolbox/ioctl.c
+++ b/toolbox/ioctl.c
@@ -21,9 +21,9 @@
     int arg_size = 4;
     int direct_arg = 0;
     uint32_t ioctl_nr;
-    void *ioctl_args;
+    void *ioctl_args = NULL;
     uint8_t *ioctl_argp;
-    uint8_t *ioctl_argp_save;
+    uint8_t *ioctl_argp_save = NULL;
     int rem;
 
     do {
@@ -112,6 +112,7 @@
     else
         res = ioctl(fd, ioctl_nr, 0);
     if (res < 0) {
+        free(ioctl_args);
         fprintf(stderr, "ioctl 0x%x failed, %d\n", ioctl_nr, res);
         return 1;
     }
@@ -124,5 +125,6 @@
         }
         printf("\n");
     }
+    free(ioctl_args);
     return 0;
 }
diff --git a/toolbox/load_policy.c b/toolbox/load_policy.c
index eb5aba6..90d48c4 100644
--- a/toolbox/load_policy.c
+++ b/toolbox/load_policy.c
@@ -10,7 +10,7 @@
 
 int load_policy_main(int argc, char **argv)
 {
-    int fd, rc, vers;
+    int fd, rc;
     struct stat sb;
     void *map;
     const char *path;
diff --git a/toolbox/ls.c b/toolbox/ls.c
index 06910ee..011f7b5 100644
--- a/toolbox/ls.c
+++ b/toolbox/ls.c
@@ -443,7 +443,6 @@
 int ls_main(int argc, char **argv)
 {
     int flags = 0;
-    int listed = 0;
 
     if(argc > 1) {
         int i;
diff --git a/toolbox/lsof.c b/toolbox/lsof.c
index af321af..bee981d 100644
--- a/toolbox/lsof.c
+++ b/toolbox/lsof.c
@@ -99,10 +99,7 @@
 static void print_maps(struct pid_info_t* info)
 {
     FILE *maps;
-    char buffer[PATH_MAX + 100];
-
     size_t offset;
-    int major, minor;
     char device[10];
     long int inode;
     char file[PATH_MAX];
diff --git a/toolbox/mkdir.c b/toolbox/mkdir.c
index 656970a..398d350 100644
--- a/toolbox/mkdir.c
+++ b/toolbox/mkdir.c
@@ -15,7 +15,6 @@
 
 int mkdir_main(int argc, char *argv[])
 {
-    int symbolic = 0;
     int ret;
     if(argc < 2 || strcmp(argv[1], "--help") == 0) {
         return usage();
diff --git a/toolbox/newfs_msdos.c b/toolbox/newfs_msdos.c
index 27dca42..30b9f77 100644
--- a/toolbox/newfs_msdos.c
+++ b/toolbox/newfs_msdos.c
@@ -360,7 +360,7 @@
     if (!opt_create && !strchr(fname, '/')) {
 	snprintf(buf, sizeof(buf), "%s%s", _PATH_DEV, fname);
 	if (!(fname = strdup(buf)))
-	    err(1, NULL);
+	    err(1, "%s", buf);
     }
     dtype = *argv;
     if (opt_create) {
@@ -493,7 +493,7 @@
 	if (!strchr(bname, '/')) {
 	    snprintf(buf, sizeof(buf), "/boot/%s", bname);
 	    if (!(bname = strdup(buf)))
-		err(1, NULL);
+		err(1, "%s", buf);
 	}
 	if ((fd1 = open(bname, O_RDONLY)) == -1 || fstat(fd1, &sb))
 	    err(1, "%s", bname);
@@ -611,7 +611,7 @@
 	now = tv.tv_sec;
 	tm = localtime(&now);
 	if (!(img = malloc(bpb.bps)))
-	    err(1, NULL);
+	    err(1, "%u", bpb.bps);
 	dir = bpb.res + (bpb.spf ? bpb.spf : bpb.bspf) * bpb.nft;
 	for (lsn = 0; lsn < dir + (fat == 32 ? bpb.spc : rds); lsn++) {
 	    x = lsn;
@@ -728,14 +728,14 @@
 static void
 check_mounted(const char *fname, mode_t mode)
 {
+#ifdef ANDROID
+    warnx("Skipping mount checks");
+#else
     struct statfs *mp;
     const char *s1, *s2;
     size_t len;
     int n, r;
 
-#ifdef ANDROID
-    warnx("Skipping mount checks");
-#else
     if (!(n = getmntinfo(&mp, MNT_NOWAIT)))
 	err(1, "getmntinfo");
     len = strlen(_PATH_DEV);
diff --git a/toolbox/ps.c b/toolbox/ps.c
index 7c35ccb..57b4280 100644
--- a/toolbox/ps.c
+++ b/toolbox/ps.c
@@ -28,9 +28,12 @@
 #define SHOW_POLICY 4
 #define SHOW_CPU  8
 #define SHOW_MACLABEL 16
+#define SHOW_ABI 32
 
 static int display_flags = 0;
 
+static void print_exe_abi(int pid);
+
 static int ps_line(int pid, int tid, char *namefilter)
 {
     char statline[1024];
@@ -40,7 +43,7 @@
     struct stat stats;
     int fd, r;
     char *ptr, *name, *state;
-    int ppid, tty;
+    int ppid;
     unsigned wchan, rss, vss, eip;
     unsigned utime, stime;
     int prio, nice, rtprio, sched, psr;
@@ -88,7 +91,7 @@
     ppid = atoi(nexttok(&ptr));
     nexttok(&ptr); // pgrp
     nexttok(&ptr); // sid
-    tty = atoi(nexttok(&ptr));
+    nexttok(&ptr); // tty
     
     nexttok(&ptr); // tpgid
     nexttok(&ptr); // flags
@@ -130,7 +133,7 @@
     rtprio = atoi(nexttok(&ptr)); // rt_priority
     sched = atoi(nexttok(&ptr)); // scheduling policy
     
-    tty = atoi(nexttok(&ptr));
+    nexttok(&ptr); // tty
     
     if(tid != 0) {
         ppid = pid;
@@ -170,7 +173,11 @@
             else
                 printf(" %.2s ", get_sched_policy_name(p));
         }
-        printf(" %08x %08x %s %s", wchan, eip, state, cmdline[0] ? cmdline : name);
+        printf(" %08x %08x %s ", wchan, eip, state);
+        if (display_flags & SHOW_ABI) {
+            print_exe_abi(pid);
+        }
+        printf("%s", cmdline[0] ? cmdline : name);
         if(display_flags&SHOW_TIME)
             printf(" (u:%d, s:%d)", utime, stime);
 
@@ -179,6 +186,39 @@
     return 0;
 }
 
+static void print_exe_abi(int pid)
+{
+    int fd, r;
+    char exeline[1024];
+
+    sprintf(exeline, "/proc/%d/exe", pid);
+    fd = open(exeline, O_RDONLY);
+    if(fd == 0) {
+        printf("    ");
+        return;
+    }
+    r = read(fd, exeline, 5 /* 4 byte ELFMAG + 1 byte EI_CLASS */);
+    close(fd);
+    if(r < 0) {
+        printf("    ");
+        return;
+    }
+    if (memcmp("\177ELF", exeline, 4) != 0) {
+        printf("??  ");
+        return;
+    }
+    switch (exeline[4]) {
+        case 1:
+            printf("32  ");
+            return;
+        case 2:
+            printf("64  ");
+            return;
+        default:
+            printf("??  ");
+            return;
+    }
+}
 
 void ps_threads(int pid, char *namefilter)
 {
@@ -224,7 +264,9 @@
             display_flags |= SHOW_PRIO;
         } else if(!strcmp(argv[1],"-c")) {
             display_flags |= SHOW_CPU;
-        }  else if(isdigit(argv[1][0])){
+        } else if(!strcmp(argv[1],"--abi")) {
+            display_flags |= SHOW_ABI;
+        } else if(isdigit(argv[1][0])){
             pidfilter = atoi(argv[1]);
         } else {
             namefilter = argv[1];
@@ -236,10 +278,11 @@
     if (display_flags & SHOW_MACLABEL) {
         printf("LABEL                          USER     PID   PPID  NAME\n");
     } else {
-        printf("USER     PID   PPID  VSIZE  RSS   %s%s %s WCHAN    PC         NAME\n",
+        printf("USER     PID   PPID  VSIZE  RSS   %s%s %s WCHAN    PC        %sNAME\n",
                (display_flags&SHOW_CPU)?"CPU ":"",
                (display_flags&SHOW_PRIO)?"PRIO  NICE  RTPRI SCHED ":"",
-               (display_flags&SHOW_POLICY)?"PCY " : "");
+               (display_flags&SHOW_POLICY)?"PCY " : "",
+               (display_flags&SHOW_ABI)?"ABI " : "");
     }
     while((de = readdir(d)) != 0){
         if(isdigit(de->d_name[0])){
diff --git a/toolbox/rmdir.c b/toolbox/rmdir.c
index 06f3df2..749fec8 100644
--- a/toolbox/rmdir.c
+++ b/toolbox/rmdir.c
@@ -11,7 +11,6 @@
 
 int rmdir_main(int argc, char *argv[])
 {
-    int symbolic = 0;
     int ret;
     if(argc < 2) return usage();
 
diff --git a/toolbox/schedtop.c b/toolbox/schedtop.c
index 0c85e76..2fccd2e 100644
--- a/toolbox/schedtop.c
+++ b/toolbox/schedtop.c
@@ -227,7 +227,6 @@
     }
     for (i = 0; i < last_processes.active; i++) {
         int pid = last_processes.data[i].pid;
-        int tid = last_processes.data[i].tid;
         for (j = 0; j < processes.active; j++)
             if (pid == processes.data[j].pid)
                 break;
@@ -270,9 +269,6 @@
 {
     int c;
     DIR *d;
-    struct dirent *de;
-    char *namefilter = 0;
-    int pidfilter = 0;
     uint32_t flags = 0;    
     int delay = 3000000;
     float delay_f;
diff --git a/toolbox/sendevent.c b/toolbox/sendevent.c
index 1608e6c..9b813f6 100644
--- a/toolbox/sendevent.c
+++ b/toolbox/sendevent.c
@@ -47,9 +47,8 @@
 
 int sendevent_main(int argc, char *argv[])
 {
-    int i;
     int fd;
-    int ret;
+    ssize_t ret;
     int version;
     struct input_event event;
 
@@ -72,7 +71,7 @@
     event.code = atoi(argv[3]);
     event.value = atoi(argv[4]);
     ret = write(fd, &event, sizeof(event));
-    if(ret < sizeof(event)) {
+    if(ret < (ssize_t) sizeof(event)) {
         fprintf(stderr, "write event failed, %s\n", strerror(errno));
         return -1;
     }
diff --git a/toolbox/start.c b/toolbox/start.c
index 665a941..0941e64 100644
--- a/toolbox/start.c
+++ b/toolbox/start.c
@@ -7,14 +7,13 @@
 
 int start_main(int argc, char *argv[])
 {
-    char buf[1024];
-
     if(argc > 1) {
         property_set("ctl.start", argv[1]);
     } else {
         /* defaults to starting the common services stopped by stop.c */
         property_set("ctl.start", "surfaceflinger");
         property_set("ctl.start", "zygote");
+        property_set("ctl.start", "zygote_secondary");
     }
 
     return 0;
diff --git a/toolbox/stop.c b/toolbox/stop.c
index 460f377..ed9a293 100644
--- a/toolbox/stop.c
+++ b/toolbox/stop.c
@@ -5,12 +5,11 @@
 
 int stop_main(int argc, char *argv[])
 {
-    char buf[1024];
-
     if(argc > 1) {
         property_set("ctl.stop", argv[1]);
     } else{
         /* defaults to stopping the common services */
+        property_set("ctl.stop", "zygote_secondary");
         property_set("ctl.stop", "zygote");
         property_set("ctl.stop", "surfaceflinger");
     }
diff --git a/toolbox/top.c b/toolbox/top.c
index 7382f1f..280a032 100644
--- a/toolbox/top.c
+++ b/toolbox/top.c
@@ -328,7 +328,6 @@
 static int read_stat(char *filename, struct proc_info *proc) {
     FILE *file;
     char buf[MAX_LINE], *open_paren, *close_paren;
-    int res, idx;
 
     file = fopen(filename, "r");
     if (!file) return 1;
@@ -414,9 +413,7 @@
     struct proc_info *old_proc, *proc;
     long unsigned total_delta_time;
     struct passwd *user;
-    struct group *group;
     char *user_str, user_buf[20];
-    char *group_str, group_buf[20];
 
     for (i = 0; i < num_new_procs; i++) {
         if (new_procs[i]) {
@@ -467,19 +464,12 @@
         if (!proc || (max_procs && (i >= max_procs)))
             break;
         user  = getpwuid(proc->uid);
-        group = getgrgid(proc->gid);
         if (user && user->pw_name) {
             user_str = user->pw_name;
         } else {
             snprintf(user_buf, 20, "%d", proc->uid);
             user_str = user_buf;
         }
-        if (group && group->gr_name) {
-            group_str = group->gr_name;
-        } else {
-            snprintf(group_buf, 20, "%d", proc->gid);
-            group_str = group_buf;
-        }
         if (!threads)
             printf("%5d %2d %3ld%% %c %5d %6ldK %6ldK %3s %-8.8s %s\n", proc->pid, proc->prs, proc->delta_time * 100 / total_delta_time, proc->state, proc->num_threads,
                 proc->vss / 1024, proc->rss * getpagesize() / 1024, proc->policy, user_str, proc->name[0] != 0 ? proc->name : proc->tname);
diff --git a/toolbox/umount.c b/toolbox/umount.c
index 890e870..3e17396 100644
--- a/toolbox/umount.c
+++ b/toolbox/umount.c
@@ -33,7 +33,6 @@
     char mount_path[256];
     char rest[256];
     int result = 0;
-    int path_length = strlen(path);
     
     f = fopen("/proc/mounts", "r");
     if (!f) {
diff --git a/toolbox/watchprops.c b/toolbox/watchprops.c
index bf82882..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>
 
@@ -23,9 +21,9 @@
 
 static void announce(char *name, char *value)
 {
-    char *x;
+    unsigned char *x;
     
-    for(x = value; *x; x++) {
+    for(x = (unsigned char *)value; *x; x++) {
         if((*x < 32) || (*x > 127)) *x = '.';
     }
 
@@ -77,9 +75,7 @@
 
 int watchprops_main(int argc, char *argv[])
 {
-    unsigned serial = 0;
-    unsigned count = 0;
-    unsigned n;
+    unsigned serial;
     
     Hashmap *watchlist = hashmapCreate(1024, str_hash, str_equals);
     if (!watchlist)
@@ -87,7 +83,7 @@
 
     __system_property_foreach(populate_watchlist, watchlist);
 
-    for(;;) {
+    for(serial = 0;;) {
         serial = __system_property_wait_any(serial);
         __system_property_foreach(update_watchlist, watchlist);
     }