Merge "Define TCP buffer sizes for HSPAP, HSDPA, HSUPA and EVDO"
diff --git a/adb/adb.c b/adb/adb.c
index f4ee448..229f3ef 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -1067,7 +1067,7 @@
 
     strncpy(hostbuf, host, sizeof(hostbuf) - 1);
     if (portstr) {
-        if (portstr - host >= sizeof(hostbuf)) {
+        if ((unsigned int)(portstr - host) >= sizeof(hostbuf)) {
             snprintf(buffer, buffer_size, "bad host name %s", host);
             return;
         }
diff --git a/adb/commandline.c b/adb/commandline.c
index 47c9bec..d2b8166 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -963,7 +963,7 @@
                 argc--;
                 argv++;
             } else {
-                product = argv[1] + 2;
+                product = argv[0] + 2;
             }
             gProductOutPath = find_product_out_path(product);
             if (gProductOutPath == NULL) {
diff --git a/adb/framebuffer_service.c b/adb/framebuffer_service.c
index 862dd91..20c08d2 100644
--- a/adb/framebuffer_service.c
+++ b/adb/framebuffer_service.c
@@ -19,6 +19,9 @@
 #include <unistd.h>
 #include <string.h>
 #include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 
 #include "fdevent.h"
 #include "adb.h"
@@ -169,6 +172,8 @@
     if(writex(fd, buf, fbinfo.size % sizeof(buf))) goto done;
 
 done:
+    TEMP_FAILURE_RETRY(waitpid(pid, NULL, 0));
+
     close(fds[0]);
     close(fds[1]);
     close(fd);
diff --git a/adb/transport_local.c b/adb/transport_local.c
index 105c502..96a24ba 100644
--- a/adb/transport_local.c
+++ b/adb/transport_local.c
@@ -266,7 +266,7 @@
 
         /* Send the 'accept' request. */
         res = adb_write(fd, _accept_req, strlen(_accept_req));
-        if (res == strlen(_accept_req)) {
+        if ((size_t)res == strlen(_accept_req)) {
             /* Wait for the response. In the response we expect 'ok' on success,
              * or 'ko' on failure. */
             res = adb_read(fd, tmp, sizeof(tmp));
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index 2a516fb..15083f4 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -1,6 +1,6 @@
 # Copyright 2005 The Android Open Source Project
 
-ifneq ($(filter arm x86,$(TARGET_ARCH)),)
+ifneq ($(filter arm mips x86,$(TARGET_ARCH)),)
 
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
@@ -25,6 +25,12 @@
 
 LOCAL_SHARED_LIBRARIES := libcutils libc libcorkscrew
 
+ifeq ($(HAVE_SELINUX),true)
+LOCAL_SHARED_LIBRARIES += libselinux
+LOCAL_C_INCLUDES += external/libselinux/include
+LOCAL_CFLAGS += -DHAVE_SELINUX
+endif
+
 include $(BUILD_EXECUTABLE)
 
 include $(CLEAR_VARS)
diff --git a/debuggerd/debuggerd.c b/debuggerd/debuggerd.c
index 8009631..55222c5 100644
--- a/debuggerd/debuggerd.c
+++ b/debuggerd/debuggerd.c
@@ -330,7 +330,10 @@
                     case SIGFPE:
                     case SIGSEGV:
                     case SIGPIPE:
-                    case SIGSTKFLT: {
+#ifdef SIGSTKFLT
+                    case SIGSTKFLT:
+#endif
+                        {
                         XLOG("stopped -- fatal signal\n");
                         /*
                          * Send a SIGSTOP to the process to make all of
@@ -424,7 +427,9 @@
     signal(SIGFPE, SIG_DFL);
     signal(SIGSEGV, SIG_DFL);
     signal(SIGPIPE, SIG_DFL);
+#ifdef SIGSTKFLT
     signal(SIGSTKFLT, SIG_DFL);
+#endif
 
     logsocket = socket_local_client("logd",
             ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_DGRAM);
diff --git a/debuggerd/mips/crashglue.S b/debuggerd/mips/crashglue.S
new file mode 100644
index 0000000..70a6641
--- /dev/null
+++ b/debuggerd/mips/crashglue.S
@@ -0,0 +1,48 @@
+	.set	noat
+
+	.globl crash1
+	.globl crashnostack
+
+crash1:
+	li	$0,0xdead0000+0
+	li	$1,0xdead0000+1
+	li	$2,0xdead0000+2
+	li	$3,0xdead0000+3
+	li	$4,0xdead0000+4
+	li	$5,0xdead0000+5
+	li	$6,0xdead0000+6
+	li	$7,0xdead0000+7
+	li	$8,0xdead0000+8
+	li	$9,0xdead0000+9
+	li	$10,0xdead0000+10
+	li	$11,0xdead0000+11
+	li	$12,0xdead0000+12
+	li	$13,0xdead0000+13
+	li	$14,0xdead0000+14
+	li	$15,0xdead0000+15
+	li	$16,0xdead0000+16
+	li	$17,0xdead0000+17
+	li	$18,0xdead0000+18
+	li	$19,0xdead0000+19
+	li	$20,0xdead0000+20
+	li	$21,0xdead0000+21
+	li	$22,0xdead0000+22
+	li	$23,0xdead0000+23
+	li	$24,0xdead0000+24
+	li	$25,0xdead0000+25
+	li	$26,0xdead0000+26
+	li	$27,0xdead0000+27
+	li	$28,0xdead0000+28
+	# don't trash the stack otherwise the signal handler won't run
+	#li	$29,0xdead0000+29
+	li	$30,0xdead0000+30
+	li	$31,0xdead0000+31
+
+	lw	$zero,($0)
+	b .
+
+
+crashnostack:
+	li	$sp, 0
+	lw	$zero,($0)
+	b .
diff --git a/debuggerd/mips/machine.c b/debuggerd/mips/machine.c
new file mode 100644
index 0000000..dba1711
--- /dev/null
+++ b/debuggerd/mips/machine.c
@@ -0,0 +1,178 @@
+/* system/debuggerd/debuggerd.c
+**
+** Copyright 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.
+*/
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+
+#include <corkscrew/ptrace.h>
+
+#include <linux/user.h>
+
+#include "../utility.h"
+#include "../machine.h"
+
+/* enable to dump memory pointed to by every register */
+#define DUMP_MEMORY_FOR_ALL_REGISTERS 1
+
+#define R(x) ((unsigned int)(x))
+
+static void dump_memory(log_t* log, pid_t tid, uintptr_t addr, bool at_fault) {
+    char code_buffer[64];       /* actual 8+1+((8+1)*4) + 1 == 45 */
+    char ascii_buffer[32];      /* actual 16 + 1 == 17 */
+    uintptr_t p, end;
+
+    p = addr & ~3;
+    p -= 32;
+    if (p > addr) {
+        /* catch underflow */
+        p = 0;
+    }
+    end = p + 80;
+    /* catch overflow; 'end - p' has to be multiples of 16 */
+    while (end < p)
+        end -= 16;
+
+    /* Dump the code around PC as:
+     *  addr     contents                             ascii
+     *  00008d34 ef000000 e8bd0090 e1b00000 512fff1e  ............../Q
+     *  00008d44 ea00b1f9 e92d0090 e3a070fc ef000000  ......-..p......
+     */
+    while (p < end) {
+        char* asc_out = ascii_buffer;
+
+        sprintf(code_buffer, "%08x ", p);
+
+        int i;
+        for (i = 0; i < 4; i++) {
+            /*
+             * If we see (data == -1 && errno != 0), we know that the ptrace
+             * call failed, probably because we're dumping memory in an
+             * unmapped or inaccessible page.  I don't know if there's
+             * value in making that explicit in the output -- it likely
+             * just complicates parsing and clarifies nothing for the
+             * enlightened reader.
+             */
+            long data = ptrace(PTRACE_PEEKTEXT, tid, (void*)p, NULL);
+            sprintf(code_buffer + strlen(code_buffer), "%08lx ", data);
+
+            int j;
+            for (j = 0; j < 4; j++) {
+                /*
+                 * Our isprint() allows high-ASCII characters that display
+                 * differently (often badly) in different viewers, so we
+                 * just use a simpler test.
+                 */
+                char val = (data >> (j*8)) & 0xff;
+                if (val >= 0x20 && val < 0x7f) {
+                    *asc_out++ = val;
+                } else {
+                    *asc_out++ = '.';
+                }
+            }
+            p += 4;
+        }
+        *asc_out = '\0';
+        _LOG(log, !at_fault, "    %s %s\n", code_buffer, ascii_buffer);
+    }
+}
+
+/*
+ * If configured to do so, dump memory around *all* registers
+ * for the crashing thread.
+ */
+void dump_memory_and_code(const ptrace_context_t* context __attribute((unused)),
+        log_t* log, pid_t tid, bool at_fault) {
+    pt_regs_mips_t r;
+    if(ptrace(PTRACE_GETREGS, tid, 0, &r)) {
+        return;
+    }
+
+    if (at_fault && DUMP_MEMORY_FOR_ALL_REGISTERS) {
+        static const char REG_NAMES[] = "$0atv0v1a0a1a2a3t0t1t2t3t4t5t6t7s0s1s2s3s4s5s6s7t8t9k0k1gpsps8ra";
+
+        for (int reg = 0; reg < 32; reg++) {
+            /* skip uninteresting registers */
+            if (reg == 0 /* $0 */
+                || reg == 26 /* $k0 */
+                || reg == 27 /* $k1 */
+                || reg == 31 /* $ra (done below) */
+               )
+               continue;
+
+            uintptr_t addr = R(r.regs[reg]);
+
+            /*
+             * Don't bother if it looks like a small int or ~= null, or if
+             * it's in the kernel area.
+             */
+            if (addr < 4096 || addr >= 0x80000000) {
+                continue;
+            }
+
+            _LOG(log, false, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
+            dump_memory(log, tid, addr, at_fault);
+        }
+    }
+
+    unsigned int pc = R(r.cp0_epc);
+    unsigned int ra = R(r.regs[31]);
+
+    _LOG(log, !at_fault, "\ncode around pc:\n");
+    dump_memory(log, tid, (uintptr_t)pc, at_fault);
+
+    if (pc != ra) {
+        _LOG(log, !at_fault, "\ncode around ra:\n");
+        dump_memory(log, tid, (uintptr_t)ra, at_fault);
+    }
+}
+
+void dump_registers(const ptrace_context_t* context __attribute((unused)),
+        log_t* log, pid_t tid, bool at_fault)
+{
+    pt_regs_mips_t r;
+    bool only_in_tombstone = !at_fault;
+
+    if(ptrace(PTRACE_GETREGS, tid, 0, &r)) {
+        _LOG(log, only_in_tombstone, "cannot get registers: %s\n", strerror(errno));
+        return;
+    }
+
+    _LOG(log, only_in_tombstone, " zr %08x  at %08x  v0 %08x  v1 %08x\n",
+     R(r.regs[0]), R(r.regs[1]), R(r.regs[2]), R(r.regs[3]));
+    _LOG(log, only_in_tombstone, " a0 %08x  a1 %08x  a2 %08x  a3 %08x\n",
+     R(r.regs[4]), R(r.regs[5]), R(r.regs[6]), R(r.regs[7]));
+    _LOG(log, only_in_tombstone, " t0 %08x  t1 %08x  t2 %08x  t3 %08x\n",
+     R(r.regs[8]), R(r.regs[9]), R(r.regs[10]), R(r.regs[11]));
+    _LOG(log, only_in_tombstone, " t4 %08x  t5 %08x  t6 %08x  t7 %08x\n",
+     R(r.regs[12]), R(r.regs[13]), R(r.regs[14]), R(r.regs[15]));
+    _LOG(log, only_in_tombstone, " s0 %08x  s1 %08x  s2 %08x  s3 %08x\n",
+     R(r.regs[16]), R(r.regs[17]), R(r.regs[18]), R(r.regs[19]));
+    _LOG(log, only_in_tombstone, " s4 %08x  s5 %08x  s6 %08x  s7 %08x\n",
+     R(r.regs[20]), R(r.regs[21]), R(r.regs[22]), R(r.regs[23]));
+    _LOG(log, only_in_tombstone, " t8 %08x  t9 %08x  k0 %08x  k1 %08x\n",
+     R(r.regs[24]), R(r.regs[25]), R(r.regs[26]), R(r.regs[27]));
+    _LOG(log, only_in_tombstone, " gp %08x  sp %08x  s8 %08x  ra %08x\n",
+     R(r.regs[28]), R(r.regs[29]), R(r.regs[30]), R(r.regs[31]));
+    _LOG(log, only_in_tombstone, " hi %08x  lo %08x bva %08x epc %08x\n",
+     R(r.hi), R(r.lo), R(r.cp0_badvaddr), R(r.cp0_epc));
+}
diff --git a/debuggerd/tombstone.c b/debuggerd/tombstone.c
index 16b4943..012337b 100644
--- a/debuggerd/tombstone.c
+++ b/debuggerd/tombstone.c
@@ -35,6 +35,10 @@
 #include <corkscrew/demangle.h>
 #include <corkscrew/backtrace.h>
 
+#ifdef HAVE_SELINUX
+#include <selinux/android.h>
+#endif
+
 #include "machine.h"
 #include "tombstone.h"
 #include "utility.h"
@@ -72,7 +76,9 @@
     case SIGFPE:     return "SIGFPE";
     case SIGSEGV:    return "SIGSEGV";
     case SIGPIPE:    return "SIGPIPE";
+#ifdef SIGSTKFLT
     case SIGSTKFLT:  return "SIGSTKFLT";
+#endif
     case SIGSTOP:    return "SIGSTOP";
     default:         return "?";
     }
@@ -680,6 +686,13 @@
     mkdir(TOMBSTONE_DIR, 0755);
     chown(TOMBSTONE_DIR, AID_SYSTEM, AID_SYSTEM);
 
+#ifdef HAVE_SELINUX
+    if (selinux_android_restorecon(TOMBSTONE_DIR) == -1) {
+        *detach_failed = false;
+        return NULL;
+    }
+#endif
+
     int fd;
     char* path = find_and_open_tombstone(&fd);
     if (!path) {
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index e3261a7..905f759 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -48,7 +48,13 @@
   LOCAL_C_INCLUDES += development/host/windows/usb/api
 endif
 
-LOCAL_STATIC_LIBRARIES := $(EXTRA_STATIC_LIBS) libzipfile libunz libext4_utils libsparse libz
+LOCAL_STATIC_LIBRARIES := \
+    $(EXTRA_STATIC_LIBS) \
+    libzipfile \
+    libunz \
+    libext4_utils_host \
+    libsparse_host \
+    libz
 
 ifneq ($(HOST_OS),windows)
 ifeq ($(HAVE_SELINUX), true)
@@ -57,8 +63,11 @@
 endif # HOST_OS != windows
 
 include $(BUILD_HOST_EXECUTABLE)
+
+
 $(call dist-for-goals,dist_files,$(LOCAL_BUILT_MODULE))
 
+
 ifeq ($(HOST_OS),linux)
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := usbtest.c usb_linux.c
diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c
index ff99173..b6eab8c 100644
--- a/fastboot/fastboot.c
+++ b/fastboot/fastboot.c
@@ -54,8 +54,6 @@
 #define O_BINARY 0
 #endif
 
-#define DEFAULT_SPARSE_LIMIT (256 * 1024 * 1024)
-
 char cur_product[FB_RESPONSE_SZ + 1];
 
 void bootimg_set_cmdline(boot_img_hdr *h, const char *cmdline);
@@ -158,6 +156,7 @@
     char *data;
     int sz;
     int fd;
+    int errno_tmp;
 
     data = 0;
     fd = open(fn, O_RDONLY);
@@ -178,8 +177,10 @@
     return data;
 
 oops:
+    errno_tmp = errno;
     close(fd);
     if(data != 0) free(data);
+    errno = errno_tmp;
     return 0;
 }
 #endif
@@ -281,7 +282,7 @@
             "  -b <base_addr>                           specify a custom kernel base address\n"
             "  -n <page size>                           specify the nand page size. default: 2048\n"
             "  -S <size>[K|M|G]                         automatically sparse files greater than\n"
-            "                                           size. default: 256M, 0 to disable\n"
+            "                                           size.  0 to disable\n"
         );
 }
 
@@ -300,7 +301,7 @@
 
     kdata = load_file(kernel, &ksize);
     if(kdata == 0) {
-        fprintf(stderr, "cannot load '%s'\n", kernel);
+        fprintf(stderr, "cannot load '%s': %s\n", kernel, strerror(errno));
         return 0;
     }
 
@@ -320,7 +321,7 @@
     if(ramdisk) {
         rdata = load_file(ramdisk, &rsize);
         if(rdata == 0) {
-            fprintf(stderr,"cannot load '%s'\n", ramdisk);
+            fprintf(stderr,"cannot load '%s': %s\n", ramdisk, strerror(errno));
             return  0;
         }
     }
@@ -535,7 +536,7 @@
         if (target_sparse_limit > 0) {
             limit = target_sparse_limit;
         } else {
-            limit = DEFAULT_SPARSE_LIMIT;
+            return 0;
         }
     }
 
@@ -566,7 +567,7 @@
     } else {
         unsigned int sz;
         data = load_file(fname, &sz);
-        if (data == 0) die("cannot load '%s'\n", fname);
+        if (data == 0) die("cannot load '%s': %s\n", fname, strerror(errno));
         fb_queue_flash(pname, data, sz);
     }
 }
@@ -594,7 +595,7 @@
     fb_queue_query_save("product", cur_product, sizeof(cur_product));
 
     zdata = load_file(fn, &zsize);
-    if (zdata == 0) die("failed to load '%s'", fn);
+    if (zdata == 0) die("failed to load '%s': %s", fn, strerror(errno));
 
     zip = init_zipfile(zdata, zsize);
     if(zip == 0) die("failed to access zipdata in '%s'");
@@ -664,12 +665,12 @@
     fname = find_item("info", product);
     if (fname == 0) die("cannot find android-info.txt");
     data = load_file(fname, &sz);
-    if (data == 0) die("could not load android-info.txt");
+    if (data == 0) die("could not load android-info.txt: %s", strerror(errno));
     setup_requirements(data, sz);
 
     fname = find_item("boot", product);
     data = load_file(fname, &sz);
-    if (data == 0) die("could not load boot.img");
+    if (data == 0) die("could not load boot.img: %s", strerror(errno));
     do_send_signature(fname);
     fb_queue_flash("boot", data, sz);
 
@@ -682,7 +683,7 @@
 
     fname = find_item("system", product);
     data = load_file(fname, &sz);
-    if (data == 0) die("could not load system.img");
+    if (data == 0) die("could not load system.img: %s", strerror(errno));
     do_send_signature(fname);
     fb_queue_flash("system", data, sz);
 }
@@ -825,7 +826,7 @@
         return 1;
     }
 
-    if (!strcmp(*argv, "devices")) {
+    if (argc > 0 && !strcmp(*argv, "devices")) {
         skip(1);
         list_devices();
         return 0;
@@ -849,7 +850,7 @@
         } else if(!strcmp(*argv, "signature")) {
             require(2);
             data = load_file(argv[1], &sz);
-            if (data == 0) die("could not load '%s'", argv[1]);
+            if (data == 0) die("could not load '%s': %s", argv[1], strerror(errno));
             if (sz != 256) die("signature must be 256 bytes");
             fb_queue_download("signature", data, sz);
             fb_queue_command("signature", "installing signature");
diff --git a/gpttool/Android.mk b/gpttool/Android.mk
index a9fffe9..b8f9844 100644
--- a/gpttool/Android.mk
+++ b/gpttool/Android.mk
@@ -7,7 +7,6 @@
 LOCAL_STATIC_LIBRARIES := libz
 
 LOCAL_MODULE := gpttool
-LOCAL_MODULE_TAGS := eng
 
 include $(BUILD_HOST_EXECUTABLE)
 
diff --git a/include/arch/linux-sh/AndroidConfig.h b/include/arch/linux-mips/AndroidConfig.h
similarity index 87%
rename from include/arch/linux-sh/AndroidConfig.h
rename to include/arch/linux-mips/AndroidConfig.h
index 818b628..2d51dc7 100644
--- a/include/arch/linux-sh/AndroidConfig.h
+++ b/include/arch/linux-mips/AndroidConfig.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2010 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.
@@ -15,7 +15,7 @@
  */
 
 /*
- * Android config -- "android-sh".  Used for SuperH device builds.
+ * Android config -- "android-mips".  Used for MIPS device builds.
  */
 #ifndef _ANDROID_CONFIG_H
 #define _ANDROID_CONFIG_H
@@ -122,7 +122,7 @@
 /*
  * Define this if we have localtime_r().
  */
-/* #define HAVE_LOCALTIME_R 1 */
+/* #define HAVE_LOCALTIME_R */
 
 /*
  * Define this if we have gethostbyname_r().
@@ -148,7 +148,7 @@
  * Define this if we have pthread_cond_timedwait_monotonic() and
  * clock_gettime(CLOCK_MONOTONIC).
  */
-/* #define HAVE_TIMEDWAIT_MONOTONIC */
+#define HAVE_TIMEDWAIT_MONOTONIC
 
 /*
  * Define this if we have linux style epoll()
@@ -163,7 +163,12 @@
  * HAVE_BIG_ENDIAN -- we are big endian.
  */
 #define HAVE_ENDIAN_H
+#if defined(__MIPSEB__)
+#define HAVE_BIG_ENDIAN
+#endif
+#if defined(__MIPSEL__)
 #define HAVE_LITTLE_ENDIAN
+#endif
 
 /*
  * We need to choose between 32-bit and 64-bit off_t.  All of our code should
@@ -190,7 +195,7 @@
  * with a memory address.  If not defined, stack crawls will not have symbolic
  * information.
  */
-#define HAVE_DLADDR 0
+#define HAVE_DLADDR 1
 
 /*
  * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
@@ -211,7 +216,21 @@
 /*
  * Add any extra platform-specific defines here.
  */
-/* #define __linux__ */ /* for SuperH */
+#ifndef __linux__
+#define __linux__ 1
+#endif
+
+#ifndef __linux
+#define __linux 1
+#endif
+
+#ifdef __unix__
+#undef __unix__
+#endif
+
+#ifdef __unix
+#undef __unix
+#endif
 
 /*
  * Define if we have <malloc.h> header
@@ -262,7 +281,7 @@
 /*
  * What CPU architecture does this platform use?
  */
-#define ARCH_SH
+#define ARCH_MIPS 1
 
 /*
  * Define if the size of enums is as short as possible,
@@ -276,13 +295,8 @@
 
 /*
  * Do we have __memcmp16()?
- *
- * TODO : Investigate the perfomance impact of __memcmp16()
- *        and implement it.
- *        This influences on dalvikVM's string performance.
- *        See dalvik/vm/InlineNative.c.
  */
-/* #define HAVE__MEMCMP16 */
+#define HAVE__MEMCMP16  1
 
 /*
  * type for the third argument to mincore().
@@ -335,21 +349,19 @@
 #define HAVE_WRITEV 1
 
 /*
- * For dalvik/libcore
+ * Define if <stdint.h> exists.
  */
-#define CANT_PASS_VALIST_AS_CHARPTR
+#define HAVE_STDINT_H 1
 
 /*
- * For external/bluez/utils/tools/hciattach.c
- * TODO : This definition should be somewhere in bionic/libc/kernel/(*).
- *        Cosider the place and move it there.
+ * Define if <stdbool.h> exists.
  */
-#define N_TTY 0
+#define HAVE_STDBOOL_H 1
 
 /*
- * Whether or not _Unwind_Context is defined as a struct.
+ * Define if <sched.h> exists.
  */
-#define HAVE_UNWIND_CONTEXT_STRUCT
+#define HAVE_SCHED_H 1
 
 /*
  * Define if pread() exists
@@ -367,13 +379,8 @@
 #define HAVE_PRINTF_ZD 1
 
 /*
- * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ * Whether or not _Unwind_Context is defined as a struct.
  */
-#define HAVE_BSD_QSORT_R 0
-
-/*
- * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
- */
-#define HAVE_GNU_QSORT_R 0
+#define HAVE_UNWIND_CONTEXT_STRUCT 1
 
 #endif /* _ANDROID_CONFIG_H */
diff --git a/include/corkscrew/ptrace.h b/include/corkscrew/ptrace.h
index 172e348..9e0da78 100644
--- a/include/corkscrew/ptrace.h
+++ b/include/corkscrew/ptrace.h
@@ -64,6 +64,19 @@
 } 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.
  */
diff --git a/include/cutils/atomic-inline.h b/include/cutils/atomic-inline.h
index 49f3e70..0b13138 100644
--- a/include/cutils/atomic-inline.h
+++ b/include/cutils/atomic-inline.h
@@ -47,8 +47,8 @@
 #include <cutils/atomic-arm.h>
 #elif defined(__i386__) || defined(__x86_64__)
 #include <cutils/atomic-x86.h>
-#elif defined(__sh__)
-/* implementation is in atomic-android-sh.c */
+#elif defined(__mips__)
+#include <cutils/atomic-mips.h>
 #else
 #error atomic operations are unsupported
 #endif
diff --git a/include/cutils/atomic-mips.h b/include/cutils/atomic-mips.h
new file mode 100644
index 0000000..49144a3
--- /dev/null
+++ b/include/cutils/atomic-mips.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_CUTILS_ATOMIC_MIPS_H
+#define ANDROID_CUTILS_ATOMIC_MIPS_H
+
+#include <stdint.h>
+
+extern inline void android_compiler_barrier(void)
+{
+    __asm__ __volatile__ ("" : : : "memory");
+}
+
+#if ANDROID_SMP == 0
+extern inline void android_memory_barrier(void)
+{
+    android_compiler_barrier();
+}
+extern inline void android_memory_store_barrier(void)
+{
+    android_compiler_barrier();
+}
+#else
+extern inline void android_memory_barrier(void)
+{
+    __asm__ __volatile__ ("sync" : : : "memory");
+}
+extern inline void android_memory_store_barrier(void)
+{
+    __asm__ __volatile__ ("sync" : : : "memory");
+}
+#endif
+
+extern inline int32_t android_atomic_acquire_load(volatile const int32_t *ptr)
+{
+    int32_t value = *ptr;
+    android_memory_barrier();
+    return value;
+}
+
+extern inline int32_t android_atomic_release_load(volatile const int32_t *ptr)
+{
+    android_memory_barrier();
+    return *ptr;
+}
+
+extern inline void android_atomic_acquire_store(int32_t value,
+                                                volatile int32_t *ptr)
+{
+    *ptr = value;
+    android_memory_barrier();
+}
+
+extern inline void android_atomic_release_store(int32_t value,
+                                                volatile int32_t *ptr)
+{
+    android_memory_barrier();
+    *ptr = value;
+}
+
+extern inline int android_atomic_cas(int32_t old_value, int32_t new_value,
+                                     volatile int32_t *ptr)
+{
+    int32_t prev, status;
+    do {
+        __asm__ __volatile__ (
+            "    ll     %[prev], (%[ptr])\n"
+            "    li     %[status], 1\n"
+            "    bne    %[prev], %[old], 9f\n"
+            "    move   %[status], %[new_value]\n"
+            "    sc     %[status], (%[ptr])\n"
+            "9:\n"
+            : [prev] "=&r" (prev), [status] "=&r" (status)
+            : [ptr] "r" (ptr), [old] "r" (old_value), [new_value] "r" (new_value)
+            );
+    } while (__builtin_expect(status == 0, 0));
+    return prev != old_value;
+}
+
+extern inline int android_atomic_acquire_cas(int32_t old_value,
+                                             int32_t new_value,
+                                             volatile int32_t *ptr)
+{
+    int status = android_atomic_cas(old_value, new_value, ptr);
+    android_memory_barrier();
+    return status;
+}
+
+extern inline int android_atomic_release_cas(int32_t old_value,
+                                             int32_t new_value,
+                                             volatile int32_t *ptr)
+{
+    android_memory_barrier();
+    return android_atomic_cas(old_value, new_value, ptr);
+}
+
+
+extern inline int32_t android_atomic_swap(int32_t new_value,
+                                          volatile int32_t *ptr)
+{
+    int32_t prev, status;
+    do {
+    __asm__ __volatile__ (
+        "    move %[status], %[new_value]\n"
+        "    ll %[prev], (%[ptr])\n"
+        "    sc %[status], (%[ptr])\n"
+        : [prev] "=&r" (prev), [status] "=&r" (status)
+        : [ptr] "r" (ptr), [new_value] "r" (new_value)
+        );
+    } while (__builtin_expect(status == 0, 0));
+    android_memory_barrier();
+    return prev;
+}
+
+extern inline int32_t android_atomic_add(int32_t increment,
+                                         volatile int32_t *ptr)
+{
+    int32_t prev, status;
+    android_memory_barrier();
+    do {
+        __asm__ __volatile__ (
+        "    ll    %[prev], (%[ptr])\n"
+        "    addu  %[status], %[prev], %[inc]\n"
+        "    sc    %[status], (%[ptr])\n"
+        :  [status] "=&r" (status), [prev] "=&r" (prev)
+        :  [ptr] "r" (ptr), [inc] "Ir" (increment)
+        );
+    } while (__builtin_expect(status == 0, 0));
+    return prev;
+}
+
+extern inline int32_t android_atomic_inc(volatile int32_t *addr)
+{
+    return android_atomic_add(1, addr);
+}
+
+extern inline int32_t android_atomic_dec(volatile int32_t *addr)
+{
+    return android_atomic_add(-1, addr);
+}
+
+extern inline int32_t android_atomic_and(int32_t value, volatile int32_t *ptr)
+{
+    int32_t prev, status;
+    android_memory_barrier();
+    do {
+        __asm__ __volatile__ (
+        "    ll    %[prev], (%[ptr])\n"
+        "    and   %[status], %[prev], %[value]\n"
+        "    sc    %[status], (%[ptr])\n"
+        : [prev] "=&r" (prev), [status] "=&r" (status)
+        : [ptr] "r" (ptr), [value] "Ir" (value)
+            );
+    } while (__builtin_expect(status == 0, 0));
+    return prev;
+}
+
+extern inline int32_t android_atomic_or(int32_t value, volatile int32_t *ptr)
+{
+    int32_t prev, status;
+    android_memory_barrier();
+    do {
+        __asm__ __volatile__ (
+        "    ll    %[prev], (%[ptr])\n"
+        "    or    %[status], %[prev], %[value]\n"
+        "    sc    %[status], (%[ptr])\n"
+        : [prev] "=&r" (prev), [status] "=&r" (status)
+        : [ptr] "r" (ptr), [value] "Ir" (value)
+            );
+    } while (__builtin_expect(status == 0, 0));
+    return prev;
+}
+
+#endif /* ANDROID_CUTILS_ATOMIC_MIPS_H */
diff --git a/include/cutils/mspace.h b/include/cutils/mspace.h
deleted file mode 100644
index 93fe48e..0000000
--- a/include/cutils/mspace.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2006 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 wrapper file for dlmalloc.h that defines prototypes for the
- * mspace_*() functions, which provide an interface for creating
- * multiple heaps.
- */
-
-#ifndef MSPACE_H_
-#define MSPACE_H_
-
-/* It's a pain getting the mallinfo stuff to work
- * with Linux, OSX, and klibc, so just turn it off
- * for now.
- * TODO: make mallinfo work
- */
-#define NO_MALLINFO 1
-
-/* Allow setting the maximum heap footprint.
- */
-#define USE_MAX_ALLOWED_FOOTPRINT 1
-
-#define USE_CONTIGUOUS_MSPACES 1
-#if USE_CONTIGUOUS_MSPACES
-#define HAVE_MMAP 0
-#define HAVE_MORECORE 1
-#define MORECORE_CONTIGUOUS 0
-#endif
-
-#define MSPACES 1
-#define ONLY_MSPACES 1
-#include "../../../../bionic/libc/bionic/dlmalloc.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
-  mspace_usable_size(void* p);
-
-  Returns the number of bytes you can actually use in
-  an allocated chunk, which may be more than you requested (although
-  often not) due to alignment and minimum size constraints.
-  You can use this many bytes without worrying about
-  overwriting other allocated objects. This is not a particularly great
-  programming practice. mspace_usable_size can be more useful in
-  debugging and assertions, for example:
-
-  p = mspace_malloc(msp, n);
-  assert(mspace_usable_size(msp, p) >= 256);
-*/
-size_t mspace_usable_size(mspace, const void*);
-
-#if USE_CONTIGUOUS_MSPACES
-/*
-  Similar to create_mspace(), but the underlying memory is
-  guaranteed to be contiguous.  No more than max_capacity
-  bytes is ever allocated to the mspace.
- */
-mspace create_contiguous_mspace(size_t starting_capacity, size_t max_capacity,
-    int locked);
-
-/*
-   Identical to create_contiguous_mspace, but labels the mapping 'mspace/name'
-   instead of 'mspace'
-*/
-mspace create_contiguous_mspace_with_name(size_t starting_capacity,
-    size_t max_capacity, int locked, const char *name);
-
-/*
-   Identical to create_contiguous_mspace, but uses previously mapped memory.
-*/
-mspace create_contiguous_mspace_with_base(size_t starting_capacity,
-    size_t max_capacity, int locked, void *base);
-
-size_t destroy_contiguous_mspace(mspace msp);
-
-/*
-   Returns the position of the "break" within the given mspace.
-*/
-void *contiguous_mspace_sbrk0(mspace msp);
-#endif
-
-/*
-  Call the handler for each block in the specified mspace.
-  chunkptr and chunklen refer to the heap-level chunk including
-  the chunk overhead, and userptr and userlen refer to the
-  user-usable part of the chunk.  If the chunk is free, userptr
-  will be NULL and userlen will be 0.  userlen is not guaranteed
-  to be the same value passed into malloc() for a given chunk;
-  it is >= the requested size.
- */
-void mspace_walk_heap(mspace msp,
-    void(*handler)(const void *chunkptr, size_t chunklen,
-        const void *userptr, size_t userlen, void *arg), void *harg);
-
-/*
-  mspace_walk_free_pages(handler, harg)
-
-  Calls the provided handler on each free region in the specified
-  mspace.  The memory between start and end are guaranteed not to
-  contain any important data, so the handler is free to alter the
-  contents in any way.  This can be used to advise the OS that large
-  free regions may be swapped out.
-
-  The value in harg will be passed to each call of the handler.
- */
-void mspace_walk_free_pages(mspace msp,
-    void(*handler)(void *start, void *end, void *arg), void *harg);
-
-#ifdef __cplusplus
-};  /* end of extern "C" */
-#endif
-
-#endif /* MSPACE_H_ */
diff --git a/include/diskconfig/diskconfig.h b/include/diskconfig/diskconfig.h
index d4f468c..d45b99e 100644
--- a/include/diskconfig/diskconfig.h
+++ b/include/diskconfig/diskconfig.h
@@ -19,6 +19,7 @@
 #define __LIBS_DISKCONFIG_H
 
 #include <stdint.h>
+#include <sys/types.h>
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/private/pixelflinger/ggl_context.h b/include/private/pixelflinger/ggl_context.h
index 2d7fdcf..4864d5a 100644
--- a/include/private/pixelflinger/ggl_context.h
+++ b/include/private/pixelflinger/ggl_context.h
@@ -42,10 +42,30 @@
 #else
 
 inline uint32_t GGL_RGBA_TO_HOST(uint32_t v) {
+#if defined(__mips__) && __mips==32 && __mips_isa_rev>=2
+    uint32_t r;
+    __asm__("wsbh %0, %1;"
+        "rotr %0, %0, 16"
+        : "=r" (r)
+        : "r" (v)
+        );
+    return r;
+#else
     return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
+#endif
 }
 inline uint32_t GGL_HOST_TO_RGBA(uint32_t v) {
+#if defined(__mips__) && __mips==32 && __mips_isa_rev>=2
+    uint32_t r;
+    __asm__("wsbh %0, %1;"
+        "rotr %0, %0, 16"
+        : "=r" (r)
+        : "r" (v)
+        );
+    return r;
+#else
     return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
+#endif
 }
 
 #endif
diff --git a/include/private/pixelflinger/ggl_fixed.h b/include/private/pixelflinger/ggl_fixed.h
index 96fdb32..217ec04 100644
--- a/include/private/pixelflinger/ggl_fixed.h
+++ b/include/private/pixelflinger/ggl_fixed.h
@@ -190,6 +190,272 @@
         );
     return res;
 }
+#elif defined(__mips__)
+
+/*inline MIPS implementations*/
+inline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) CONST;
+inline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) {
+    GGLfixed result,tmp,tmp1,tmp2;
+
+    if (__builtin_constant_p(shift)) {
+        if (shift == 0) {
+            asm ("mult %[a], %[b] \t\n"
+              "mflo  %[res]   \t\n"
+            : [res]"=&r"(result),[tmp]"=&r"(tmp)
+            : [a]"r"(a),[b]"r"(b)
+            : "%hi","%lo"
+            );
+        } else if (shift == 32)
+        {
+            asm ("mult %[a], %[b] \t\n"
+            "li  %[tmp],1\t\n"
+            "sll  %[tmp],%[tmp],0x1f\t\n"
+            "mflo %[res]   \t\n"
+            "addu %[tmp1],%[tmp],%[res] \t\n"
+            "sltu %[tmp1],%[tmp1],%[tmp]\t\n"   /*obit*/
+            "sra %[tmp],%[tmp],0x1f \t\n"
+            "mfhi  %[res]   \t\n"
+            "addu %[res],%[res],%[tmp]\t\n"
+            "addu %[res],%[res],%[tmp1]\t\n"
+            : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1)
+            : [a]"r"(a),[b]"r"(b),[shift]"I"(shift)
+            : "%hi","%lo"
+            );
+        } else if ((shift >0) && (shift < 32))
+        {
+            asm ("mult %[a], %[b] \t\n"
+            "li  %[tmp],1 \t\n"
+            "sll  %[tmp],%[tmp],%[shiftm1] \t\n"
+            "mflo  %[res]   \t\n"
+            "addu %[tmp1],%[tmp],%[res] \t\n"
+            "sltu %[tmp1],%[tmp1],%[tmp] \t\n"  /*obit?*/
+            "addu  %[res],%[res],%[tmp] \t\n"
+            "mfhi  %[tmp]   \t\n"
+            "addu  %[tmp],%[tmp],%[tmp1] \t\n"
+            "sll   %[tmp],%[tmp],%[lshift] \t\n"
+            "srl   %[res],%[res],%[rshift]    \t\n"
+            "or    %[res],%[res],%[tmp] \t\n"
+            : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
+            : [a]"r"(a),[b]"r"(b),[lshift]"I"(32-shift),[rshift]"I"(shift),[shiftm1]"I"(shift-1)
+            : "%hi","%lo"
+            );
+        } else {
+            asm ("mult %[a], %[b] \t\n"
+            "li  %[tmp],1 \t\n"
+            "sll  %[tmp],%[tmp],%[shiftm1] \t\n"
+            "mflo  %[res]   \t\n"
+            "addu %[tmp1],%[tmp],%[res] \t\n"
+            "sltu %[tmp1],%[tmp1],%[tmp] \t\n"  /*obit?*/
+            "sra  %[tmp2],%[tmp],0x1f \t\n"
+            "addu  %[res],%[res],%[tmp] \t\n"
+            "mfhi  %[tmp]   \t\n"
+            "addu  %[tmp],%[tmp],%[tmp2] \t\n"
+            "addu  %[tmp],%[tmp],%[tmp1] \t\n"            /*tmp=hi*/
+            "srl   %[tmp2],%[res],%[rshift]    \t\n"
+            "srav  %[res], %[tmp],%[rshift]\t\n"
+            "sll   %[tmp],%[tmp],1 \t\n"
+            "sll   %[tmp],%[tmp],%[norbits] \t\n"
+            "or    %[tmp],%[tmp],%[tmp2] \t\n"
+            "movz  %[res],%[tmp],%[bit5] \t\n"
+            : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
+            : [a]"r"(a),[b]"r"(b),[norbits]"I"(~(shift)),[rshift]"I"(shift),[shiftm1] "I"(shift-1),[bit5]"I"(shift & 0x20)
+            : "%hi","%lo"
+            );
+        }
+    } else {
+        asm ("mult %[a], %[b] \t\n"
+        "li  %[tmp],1 \t\n"
+        "sll  %[tmp],%[tmp],%[shiftm1] \t\n"
+        "mflo  %[res]   \t\n"
+        "addu %[tmp1],%[tmp],%[res] \t\n"
+        "sltu %[tmp1],%[tmp1],%[tmp] \t\n"  /*obit?*/
+        "sra  %[tmp2],%[tmp],0x1f \t\n"
+        "addu  %[res],%[res],%[tmp] \t\n"
+        "mfhi  %[tmp]   \t\n"
+        "addu  %[tmp],%[tmp],%[tmp2] \t\n"
+        "addu  %[tmp],%[tmp],%[tmp1] \t\n"            /*tmp=hi*/
+        "srl   %[tmp2],%[res],%[rshift]    \t\n"
+        "srav  %[res], %[tmp],%[rshift]\t\n"
+        "sll   %[tmp],%[tmp],1 \t\n"
+        "sll   %[tmp],%[tmp],%[norbits] \t\n"
+        "or    %[tmp],%[tmp],%[tmp2] \t\n"
+        "movz  %[res],%[tmp],%[bit5] \t\n"
+         : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
+         : [a]"r"(a),[b]"r"(b),[norbits]"r"(~(shift)),[rshift] "r"(shift),[shiftm1]"r"(shift-1),[bit5] "r"(shift & 0x20)
+         : "%hi","%lo"
+         );
+        }
+
+        return result;
+}
+
+inline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST;
+inline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) {
+    GGLfixed result,t,tmp1,tmp2;
+
+    if (__builtin_constant_p(shift)) {
+        if (shift == 0) {
+                 asm ("mult %[a], %[b] \t\n"
+                 "mflo  %[lo]   \t\n"
+                 "addu  %[lo],%[lo],%[c]    \t\n"
+                 : [lo]"=&r"(result)
+                 : [a]"r"(a),[b]"r"(b),[c]"r"(c)
+                 : "%hi","%lo"
+                 );
+                } else if (shift == 32) {
+                    asm ("mult %[a], %[b] \t\n"
+                    "mfhi  %[lo]   \t\n"
+                    "addu  %[lo],%[lo],%[c]    \t\n"
+                    : [lo]"=&r"(result)
+                    : [a]"r"(a),[b]"r"(b),[c]"r"(c)
+                    : "%hi","%lo"
+                    );
+                } else if ((shift>0) && (shift<32)) {
+                    asm ("mult %[a], %[b] \t\n"
+                    "mflo  %[res]   \t\n"
+                    "mfhi  %[t]   \t\n"
+                    "srl   %[res],%[res],%[rshift]    \t\n"
+                    "sll   %[t],%[t],%[lshift]     \t\n"
+                    "or  %[res],%[res],%[t]    \t\n"
+                    "addu  %[res],%[res],%[c]    \t\n"
+                    : [res]"=&r"(result),[t]"=&r"(t)
+                    : [a]"r"(a),[b]"r"(b),[c]"r"(c),[lshift]"I"(32-shift),[rshift]"I"(shift)
+                    : "%hi","%lo"
+                    );
+                } else {
+                    asm ("mult %[a], %[b] \t\n"
+                    "nor %[tmp1],$zero,%[shift]\t\n"
+                    "mflo  %[res]   \t\n"
+                    "mfhi  %[t]   \t\n"
+                    "srl   %[res],%[res],%[shift]    \t\n"
+                    "sll   %[tmp2],%[t],1     \t\n"
+                    "sllv  %[tmp2],%[tmp2],%[tmp1]     \t\n"
+                    "or  %[tmp1],%[tmp2],%[res]    \t\n"
+                    "srav  %[res],%[t],%[shift]     \t\n"
+                    "andi %[tmp2],%[shift],0x20\t\n"
+                    "movz %[res],%[tmp1],%[tmp2]\t\n"
+                    "addu  %[res],%[res],%[c]    \t\n"
+                    : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
+                    : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"I"(shift)
+                    : "%hi","%lo"
+                    );
+                }
+            } else {
+                asm ("mult %[a], %[b] \t\n"
+                "nor %[tmp1],$zero,%[shift]\t\n"
+                "mflo  %[res]   \t\n"
+                "mfhi  %[t]   \t\n"
+                "srl   %[res],%[res],%[shift]    \t\n"
+                "sll   %[tmp2],%[t],1     \t\n"
+                "sllv  %[tmp2],%[tmp2],%[tmp1]     \t\n"
+                "or  %[tmp1],%[tmp2],%[res]    \t\n"
+                "srav  %[res],%[t],%[shift]     \t\n"
+                "andi %[tmp2],%[shift],0x20\t\n"
+                "movz %[res],%[tmp1],%[tmp2]\t\n"
+                "addu  %[res],%[res],%[c]    \t\n"
+                : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
+                : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"r"(shift)
+                : "%hi","%lo"
+                );
+            }
+            return result;
+}
+
+inline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST;
+inline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) {
+    GGLfixed result,t,tmp1,tmp2;
+
+    if (__builtin_constant_p(shift)) {
+        if (shift == 0) {
+                 asm ("mult %[a], %[b] \t\n"
+                 "mflo  %[lo]   \t\n"
+                 "subu  %[lo],%[lo],%[c]    \t\n"
+                 : [lo]"=&r"(result)
+                 : [a]"r"(a),[b]"r"(b),[c]"r"(c)
+                 : "%hi","%lo"
+                 );
+                } else if (shift == 32) {
+                    asm ("mult %[a], %[b] \t\n"
+                    "mfhi  %[lo]   \t\n"
+                    "subu  %[lo],%[lo],%[c]    \t\n"
+                    : [lo]"=&r"(result)
+                    : [a]"r"(a),[b]"r"(b),[c]"r"(c)
+                    : "%hi","%lo"
+                    );
+                } else if ((shift>0) && (shift<32)) {
+                    asm ("mult %[a], %[b] \t\n"
+                    "mflo  %[res]   \t\n"
+                    "mfhi  %[t]   \t\n"
+                    "srl   %[res],%[res],%[rshift]    \t\n"
+                    "sll   %[t],%[t],%[lshift]     \t\n"
+                    "or  %[res],%[res],%[t]    \t\n"
+                    "subu  %[res],%[res],%[c]    \t\n"
+                    : [res]"=&r"(result),[t]"=&r"(t)
+                    : [a]"r"(a),[b]"r"(b),[c]"r"(c),[lshift]"I"(32-shift),[rshift]"I"(shift)
+                    : "%hi","%lo"
+                    );
+                } else {
+                    asm ("mult %[a], %[b] \t\n"
+                    "nor %[tmp1],$zero,%[shift]\t\n"
+                     "mflo  %[res]   \t\n"
+                     "mfhi  %[t]   \t\n"
+                     "srl   %[res],%[res],%[shift]    \t\n"
+                     "sll   %[tmp2],%[t],1     \t\n"
+                     "sllv  %[tmp2],%[tmp2],%[tmp1]     \t\n"
+                     "or  %[tmp1],%[tmp2],%[res]    \t\n"
+                     "srav  %[res],%[t],%[shift]     \t\n"
+                     "andi %[tmp2],%[shift],0x20\t\n"
+                     "movz %[res],%[tmp1],%[tmp2]\t\n"
+                     "subu  %[res],%[res],%[c]    \t\n"
+                     : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
+                     : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"I"(shift)
+                     : "%hi","%lo"
+                     );
+                    }
+                } else {
+                asm ("mult %[a], %[b] \t\n"
+                "nor %[tmp1],$zero,%[shift]\t\n"
+                "mflo  %[res]   \t\n"
+                "mfhi  %[t]   \t\n"
+                "srl   %[res],%[res],%[shift]    \t\n"
+                "sll   %[tmp2],%[t],1     \t\n"
+                "sllv  %[tmp2],%[tmp2],%[tmp1]     \t\n"
+                "or  %[tmp1],%[tmp2],%[res]    \t\n"
+                "srav  %[res],%[t],%[shift]     \t\n"
+                "andi %[tmp2],%[shift],0x20\t\n"
+                "movz %[res],%[tmp1],%[tmp2]\t\n"
+                "subu  %[res],%[res],%[c]    \t\n"
+                : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2)
+                : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"r"(shift)
+                : "%hi","%lo"
+                );
+            }
+    return result;
+}
+
+inline int64_t gglMulii(int32_t x, int32_t y) CONST;
+inline int64_t gglMulii(int32_t x, int32_t y) {
+    union {
+        struct {
+#if defined(__MIPSEL__)
+            int32_t lo;
+            int32_t hi;
+#elif defined(__MIPSEB__)
+            int32_t hi;
+            int32_t lo;
+#endif
+        } s;
+        int64_t res;
+    }u;
+    asm("mult %2, %3 \t\n"
+        "mfhi %1   \t\n"
+        "mflo %0   \t\n"
+        : "=r"(u.s.lo), "=&r"(u.s.hi)
+        : "%r"(x), "r"(y)
+	: "%hi","%lo"
+        );
+    return u.res;
+}
 
 #else // ----------------------------------------------------------------------
 
@@ -232,7 +498,7 @@
 inline int32_t gglClz(int32_t x) CONST;
 inline int32_t gglClz(int32_t x)
 {
-#if defined(__arm__) && !defined(__thumb__)
+#if (defined(__arm__) && !defined(__thumb__)) || defined(__mips__)
     return __builtin_clz(x);
 #else
     if (!x) return 32;
diff --git a/init/builtins.c b/init/builtins.c
index ac9585e..882ceb5 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -302,7 +302,7 @@
         mode = strtoul(args[2], 0, 8);
     }
 
-    ret = mkdir(args[1], mode);
+    ret = make_dir(args[1], mode);
     /* chmod in case the directory already exists */
     if (ret == -1 && errno == EEXIST) {
         ret = _chmod(args[1], mode);
@@ -736,26 +736,12 @@
 }
 
 int do_restorecon(int nargs, char **args) {
-#ifdef HAVE_SELINUX
-    char *secontext = NULL;
-    struct stat sb;
     int i;
 
-    if (is_selinux_enabled() <= 0 || !sehandle)
-        return 0;
-
     for (i = 1; i < nargs; i++) {
-        if (lstat(args[i], &sb) < 0)
+        if (restorecon(args[i]) < 0)
             return -errno;
-        if (selabel_lookup(sehandle, &secontext, args[i], sb.st_mode) < 0)
-            return -errno;
-        if (lsetfilecon(args[i], secontext) < 0) {
-            freecon(secontext);
-            return -errno;
-        }
-        freecon(secontext);
     }
-#endif
     return 0;
 }
 
@@ -813,6 +799,8 @@
 {
     if (nargs == 2) {
         return wait_for_file(args[1], COMMAND_RETRY_TIMEOUT);
-    }
-    return -1;
+    } else if (nargs == 3) {
+        return wait_for_file(args[1], atoi(args[2]));
+    } else
+        return -1;
 }
diff --git a/init/devices.c b/init/devices.c
index 125f981..e43dbaf 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -33,6 +33,7 @@
 #ifdef HAVE_SELINUX
 #include <selinux/selinux.h>
 #include <selinux/label.h>
+#include <selinux/android.h>
 #endif
 
 #include <private/android_filesystem_config.h>
@@ -52,7 +53,7 @@
 #define FIRMWARE_DIR2   "/vendor/firmware"
 
 #ifdef HAVE_SELINUX
-static struct selabel_handle *sehandle;
+extern struct selabel_handle *sehandle;
 #endif
 
 static int device_fd = -1;
@@ -220,32 +221,6 @@
 #endif
 }
 
-
-static int make_dir(const char *path, mode_t mode)
-{
-    int rc;
-
-#ifdef HAVE_SELINUX
-    char *secontext = NULL;
-
-    if (sehandle) {
-        selabel_lookup(sehandle, &secontext, path, mode);
-        setfscreatecon(secontext);
-    }
-#endif
-
-    rc = mkdir(path, mode);
-
-#ifdef HAVE_SELINUX
-    if (secontext) {
-        freecon(secontext);
-        setfscreatecon(NULL);
-    }
-#endif
-    return rc;
-}
-
-
 static void add_platform_device(const char *name)
 {
     int name_len = strlen(name);
@@ -624,6 +599,9 @@
      } else if (!strncmp(uevent->subsystem, "graphics", 8)) {
          base = "/dev/graphics/";
          make_dir(base, 0755);
+     } else if (!strncmp(uevent->subsystem, "drm", 3)) {
+         base = "/dev/dri/";
+         make_dir(base, 0755);
      } else if (!strncmp(uevent->subsystem, "oncrpc", 6)) {
          base = "/dev/oncrpc/";
          make_dir(base, 0755);
@@ -897,12 +875,10 @@
     struct stat info;
     int fd;
 #ifdef HAVE_SELINUX
-    struct selinux_opt seopts[] = {
-        { SELABEL_OPT_PATH, "/file_contexts" }
-    };
-
-    if (is_selinux_enabled() > 0)
-        sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);
+    sehandle = NULL;
+    if (is_selinux_enabled() > 0) {
+        sehandle = selinux_android_file_context_handle();
+    }
 #endif
     /* is 64K enough? udev uses 16MB! */
     device_fd = uevent_open_socket(64*1024, true);
diff --git a/init/init.c b/init/init.c
index 4f57144..b2e39bd 100755
--- a/init/init.c
+++ b/init/init.c
@@ -33,9 +33,9 @@
 #include <sys/un.h>
 
 #ifdef HAVE_SELINUX
-#include <sys/mman.h>
 #include <selinux/selinux.h>
 #include <selinux/label.h>
+#include <selinux/android.h>
 #endif
 
 #include <libgen.h>
@@ -61,6 +61,7 @@
 
 #ifdef HAVE_SELINUX
 struct selabel_handle *sehandle;
+struct selabel_handle *sehandle_prop;
 #endif
 
 static int property_triggers_enabled = 0;
@@ -77,7 +78,6 @@
 
 #ifdef HAVE_SELINUX
 static int selinux_enabled = 1;
-static int selinux_enforcing = 0;
 #endif
 
 static struct action *cur_action = NULL;
@@ -604,9 +604,7 @@
     if (name_len == 0) return;
 
 #ifdef HAVE_SELINUX
-    if (!strcmp(name,"enforcing")) {
-        selinux_enforcing = atoi(value);
-    } else if (!strcmp(name,"selinux")) {
+    if (!strcmp(name,"selinux")) {
         selinux_enabled = atoi(value);
     }
 #endif
@@ -758,94 +756,64 @@
 #endif
 
 #ifdef HAVE_SELINUX
-void selinux_load_policy(void)
+static const struct selinux_opt seopts_prop[] = {
+        { SELABEL_OPT_PATH, "/data/system/property_contexts" },
+        { SELABEL_OPT_PATH, "/property_contexts" },
+        { 0, NULL }
+};
+
+struct selabel_handle* selinux_android_prop_context_handle(void)
 {
-    const char path_prefix[] = "/sepolicy";
-    struct selinux_opt seopts[] = {
-        { SELABEL_OPT_PATH, "/file_contexts" }
-    };
-    char path[PATH_MAX];
-    int fd, rc, vers;
-    struct stat sb;
-    void *map;
-
-    sehandle = NULL;
-    if (!selinux_enabled) {
-        INFO("SELinux:  Disabled by command line option\n");
-        return;
+    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++;
     }
 
-    mkdir(SELINUXMNT, 0755);
-    if (mount("selinuxfs", SELINUXMNT, "selinuxfs", 0, NULL)) {
-        if (errno == ENODEV) {
-            /* SELinux not enabled in kernel */
-            return;
-        }
-        ERROR("SELinux:  Could not mount selinuxfs:  %s\n",
-              strerror(errno));
-        return;
-    }
-    set_selinuxmnt(SELINUXMNT);
-
-    vers = security_policyvers();
-    if (vers <= 0) {
-        ERROR("SELinux:  Unable to read policy version\n");
-        return;
-    }
-    INFO("SELinux:  Maximum supported policy version:  %d\n", vers);
-
-    snprintf(path, sizeof(path), "%s.%d",
-             path_prefix, vers);
-    fd = open(path, O_RDONLY);
-    while (fd < 0 && errno == ENOENT && --vers) {
-        snprintf(path, sizeof(path), "%s.%d",
-                 path_prefix, vers);
-        fd = open(path, O_RDONLY);
-    }
-    if (fd < 0) {
-        ERROR("SELinux:  Could not open %s:  %s\n",
-              path, strerror(errno));
-        return;
-    }
-    if (fstat(fd, &sb) < 0) {
-        ERROR("SELinux:  Could not stat %s:  %s\n",
-              path, strerror(errno));
-        return;
-    }
-    map = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-    if (map == MAP_FAILED) {
-        ERROR("SELinux:  Could not map %s:  %s\n",
-              path, strerror(errno));
-        return;
-    }
-
-    rc = security_load_policy(map, sb.st_size);
-    if (rc < 0) {
-        ERROR("SELinux:  Could not load policy:  %s\n",
-              strerror(errno));
-        return;
-    }
-
-    rc = security_setenforce(selinux_enforcing);
-    if (rc < 0) {
-        ERROR("SELinux:  Could not set enforcing mode to %s:  %s\n",
-              selinux_enforcing ? "enforcing" : "permissive", strerror(errno));
-        return;
-    }
-
-    munmap(map, sb.st_size);
-    close(fd);
-    INFO("SELinux: Loaded policy from %s\n", path);
-
-    sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);
     if (!sehandle) {
-        ERROR("SELinux:  Could not load file_contexts:  %s\n",
+        ERROR("SELinux:  Could not load property_contexts:  %s\n",
               strerror(errno));
-        return;
+        return NULL;
     }
-    INFO("SELinux: Loaded file contexts from %s\n", seopts[0].value);
-    return;
+    INFO("SELinux: Loaded property contexts from %s\n", seopts_prop[i - 1].value);
+    return sehandle;
 }
+
+void selinux_init_all_handles(void)
+{
+    sehandle = selinux_android_file_context_handle();
+    sehandle_prop = selinux_android_prop_context_handle();
+}
+
+int selinux_reload_policy(void)
+{
+    if (!selinux_enabled) {
+        return -1;
+    }
+
+    INFO("SELinux: Attempting to reload policy files\n");
+
+    if (selinux_android_reload_policy() == -1) {
+        return -1;
+    }
+
+    if (sehandle)
+        selabel_close(sehandle);
+
+    if (sehandle_prop)
+        selabel_close(sehandle_prop);
+
+    selinux_init_all_handles();
+    return 0;
+}
+
+int audit_callback(void *data, security_class_t cls, char *buf, size_t len)
+{
+    snprintf(buf, len, "property=%s", !data ? "NULL" : (char *)data);
+    return 0;
+}
+
 #endif
 
 int main(int argc, char **argv)
@@ -899,8 +867,30 @@
     process_kernel_cmdline();
 
 #ifdef HAVE_SELINUX
+    union selinux_callback cb;
+    cb.func_log = klog_write;
+    selinux_set_callback(SELINUX_CB_LOG, cb);
+
+    cb.func_audit = audit_callback;
+    selinux_set_callback(SELINUX_CB_AUDIT, cb);
+
     INFO("loading selinux policy\n");
-    selinux_load_policy();
+    if (selinux_enabled) {
+        if (selinux_android_load_policy() < 0) {
+            selinux_enabled = 0;
+            INFO("SELinux: Disabled due to failed policy load\n");
+        } else {
+            selinux_init_all_handles();
+        }
+    } else {
+        INFO("SELinux:  Disabled by command line option\n");
+    }
+    /* These directories were necessarily created before initial policy load
+     * and therefore need their security context restored to the proper value.
+     * This must happen before /dev is populated by ueventd.
+     */
+    restorecon("/dev");
+    restorecon("/dev/socket");
 #endif
 
     is_charger = !strcmp(bootmode, "charger");
diff --git a/init/init.h b/init/init.h
index 58bbbfe..b7e06c9 100644
--- a/init/init.h
+++ b/init/init.h
@@ -138,6 +138,8 @@
 
 #ifdef HAVE_SELINUX
 extern struct selabel_handle *sehandle;
+extern struct selabel_handle *sehandle_prop;
+extern int selinux_reload_policy(void);
 #endif
 
 #endif	/* _INIT_INIT_H */
diff --git a/init/property_service.c b/init/property_service.c
index 79914cd..5017375 100644
--- a/init/property_service.c
+++ b/init/property_service.c
@@ -40,6 +40,11 @@
 #include <sys/atomics.h>
 #include <private/android_filesystem_config.h>
 
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+#endif
+
 #include "property_service.h"
 #include "init.h"
 #include "util.h"
@@ -86,6 +91,7 @@
     { "persist.sys.",     AID_SYSTEM,   0 },
     { "persist.service.", AID_SYSTEM,   0 },
     { "persist.security.", AID_SYSTEM,   0 },
+    { "selinux."         , AID_SYSTEM,   0 },
     { NULL, 0, 0 }
 };
 
@@ -191,23 +197,77 @@
     __futex_wake(&pi->serial, INT32_MAX);
 }
 
+static int check_mac_perms(const char *name, char *sctx)
+{
+#ifdef HAVE_SELINUX
+    if (is_selinux_enabled() <= 0)
+        return 1;
+
+    char *tctx = NULL;
+    const char *class = "property_service";
+    const char *perm = "set";
+    int result = 0;
+
+    if (!sctx)
+        goto err;
+
+    if (!sehandle_prop)
+        goto err;
+
+    if (selabel_lookup(sehandle_prop, &tctx, name, 1) != 0)
+        goto err;
+
+    if (selinux_check_access(sctx, tctx, class, perm, name) == 0)
+        result = 1;
+
+    freecon(tctx);
+ err:
+    return result;
+
+#endif
+    return 1;
+}
+
+static int check_control_mac_perms(const char *name, char *sctx)
+{
+#ifdef HAVE_SELINUX
+
+    /*
+     *  Create a name prefix out of ctl.<service name>
+     *  The new prefix allows the use of the existing
+     *  property service backend labeling while avoiding
+     *  mislabels based on true property prefixes.
+     */
+    char ctl_name[PROP_VALUE_MAX+4];
+    int ret = snprintf(ctl_name, sizeof(ctl_name), "ctl.%s", name);
+
+    if (ret < 0 || (size_t) ret >= sizeof(ctl_name))
+        return 0;
+
+    return check_mac_perms(ctl_name, sctx);
+
+#endif
+    return 1;
+}
+
 /*
  * Checks permissions for starting/stoping system services.
  * AID_SYSTEM and AID_ROOT are always allowed.
  *
  * Returns 1 if uid allowed, 0 otherwise.
  */
-static int check_control_perms(const char *name, unsigned int uid, unsigned int gid) {
+static int check_control_perms(const char *name, unsigned int uid, unsigned int gid, char *sctx) {
+
     int i;
     if (uid == AID_SYSTEM || uid == AID_ROOT)
-        return 1;
+      return check_control_mac_perms(name, sctx);
 
     /* Search the ACL */
     for (i = 0; control_perms[i].service; i++) {
         if (strcmp(control_perms[i].service, name) == 0) {
             if ((uid && control_perms[i].uid == uid) ||
                 (gid && control_perms[i].gid == gid)) {
-                return 1;
+                return check_control_mac_perms(name, sctx);
             }
         }
     }
@@ -218,22 +278,22 @@
  * Checks permissions for setting system properties.
  * Returns 1 if uid allowed, 0 otherwise.
  */
-static int check_perms(const char *name, unsigned int uid, unsigned int gid)
+static int check_perms(const char *name, unsigned int uid, unsigned int gid, char *sctx)
 {
     int i;
-    if (uid == 0)
-        return 1;
-
     if(!strncmp(name, "ro.", 3))
         name +=3;
 
+    if (uid == 0)
+        return check_mac_perms(name, sctx);
+
     for (i = 0; property_perms[i].prefix; i++) {
-        int tmp;
         if (strncmp(property_perms[i].prefix, name,
                     strlen(property_perms[i].prefix)) == 0) {
             if ((uid && property_perms[i].uid == uid) ||
                 (gid && property_perms[i].gid == gid)) {
-                return 1;
+
+                return check_mac_perms(name, sctx);
             }
         }
     }
@@ -334,6 +394,11 @@
          * to prevent them from being overwritten by default values.
          */
         write_persistent_property(name, value);
+#ifdef HAVE_SELINUX
+    } else if (strcmp("selinux.reload_policy", name) == 0 &&
+               strcmp("1", value) == 0) {
+        selinux_reload_policy();
+#endif
     }
     property_changed(name, value);
     return 0;
@@ -349,6 +414,7 @@
     struct sockaddr_un addr;
     socklen_t addr_size = sizeof(addr);
     socklen_t cr_size = sizeof(cr);
+    char * source_ctx = NULL;
 
     if ((s = accept(property_set_fd, (struct sockaddr *) &addr, &addr_size)) < 0) {
         return;
@@ -374,18 +440,22 @@
         msg.name[PROP_NAME_MAX-1] = 0;
         msg.value[PROP_VALUE_MAX-1] = 0;
 
+#ifdef HAVE_SELINUX
+        getpeercon(s, &source_ctx);
+#endif
+
         if(memcmp(msg.name,"ctl.",4) == 0) {
             // Keep the old close-socket-early behavior when handling
             // ctl.* properties.
             close(s);
-            if (check_control_perms(msg.value, cr.uid, cr.gid)) {
+            if (check_control_perms(msg.value, cr.uid, cr.gid, source_ctx)) {
                 handle_control_message((char*) msg.name + 4, (char*) msg.value);
             } else {
                 ERROR("sys_prop: Unable to %s service ctl [%s] uid:%d gid:%d pid:%d\n",
                         msg.name + 4, msg.value, cr.uid, cr.gid, cr.pid);
             }
         } else {
-            if (check_perms(msg.name, cr.uid, cr.gid)) {
+            if (check_perms(msg.name, cr.uid, cr.gid, source_ctx)) {
                 property_set((char*) msg.name, (char*) msg.value);
             } else {
                 ERROR("sys_prop: permission denied uid:%d  name:%s\n",
@@ -397,6 +467,10 @@
             // the property is written to memory.
             close(s);
         }
+#ifdef HAVE_SELINUX
+        freecon(source_ctx);
+#endif
+
         break;
 
     default:
diff --git a/init/readme.txt b/init/readme.txt
index df524a6..fe0d15d 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -207,6 +207,11 @@
    Trigger an event.  Used to queue an action from another
    action.
 
+wait <path> [ <timeout> ]
+  Poll for the existence of the given file and return when found,
+  or the timeout has been reached. If timeout is not specified it
+  currently defaults to five seconds.
+
 write <path> <string> [ <string> ]*
    Open the file at <path> and write one or more strings
    to it with write(2)
diff --git a/init/signal_handler.c b/init/signal_handler.c
index b170132..abccb40 100644
--- a/init/signal_handler.c
+++ b/init/signal_handler.c
@@ -131,11 +131,9 @@
     int s[2];
 
     struct sigaction act;
-
+    memset(&act, 0, sizeof(act));
     act.sa_handler = sigchld_handler;
     act.sa_flags = SA_NOCLDSTOP;
-    act.sa_mask = 0;
-    act.sa_restorer = NULL;
     sigaction(SIGCHLD, &act, 0);
 
     /* create a signalling mechanism for the sigchld handler */
diff --git a/init/util.c b/init/util.c
index 7d79f39..743748b 100755
--- a/init/util.c
+++ b/init/util.c
@@ -47,7 +47,7 @@
  */
 static unsigned int android_name_to_id(const char *name)
 {
-    struct android_id_info *info = android_ids;
+    const struct android_id_info *info = android_ids;
     unsigned int n;
 
     for (n = 0; n < android_id_count; n++) {
@@ -302,12 +302,12 @@
         memcpy(buf, pathname, width);
         buf[width] = 0;
         if (stat(buf, &info) != 0) {
-            ret = mkdir(buf, mode);
+            ret = make_dir(buf, mode);
             if (ret && errno != EEXIST)
                 return ret;
         }
     }
-    ret = mkdir(pathname, mode);
+    ret = make_dir(pathname, mode);
     if (ret && errno != EEXIST)
         return ret;
     return 0;
@@ -463,3 +463,52 @@
         ptr = x;
     }
 }
+
+int make_dir(const char *path, mode_t mode)
+{
+    int rc;
+
+#ifdef HAVE_SELINUX
+    char *secontext = NULL;
+
+    if (sehandle) {
+        selabel_lookup(sehandle, &secontext, path, mode);
+        setfscreatecon(secontext);
+    }
+#endif
+
+    rc = mkdir(path, mode);
+
+#ifdef HAVE_SELINUX
+    if (secontext) {
+        int save_errno = errno;
+        freecon(secontext);
+        setfscreatecon(NULL);
+        errno = save_errno;
+    }
+#endif
+    return rc;
+}
+
+int restorecon(const char *pathname)
+{
+#ifdef HAVE_SELINUX
+    char *secontext = NULL;
+    struct stat sb;
+    int i;
+
+    if (is_selinux_enabled() <= 0 || !sehandle)
+        return 0;
+
+    if (lstat(pathname, &sb) < 0)
+        return -errno;
+    if (selabel_lookup(sehandle, &secontext, pathname, sb.st_mode) < 0)
+        return -errno;
+    if (lsetfilecon(pathname, secontext) < 0) {
+        freecon(secontext);
+        return -errno;
+    }
+    freecon(secontext);
+#endif
+    return 0;
+}
diff --git a/init/util.h b/init/util.h
index 9247739..45905b6 100644
--- a/init/util.h
+++ b/init/util.h
@@ -39,4 +39,6 @@
 void open_devnull_stdio(void);
 void get_hardware_name(char *hardware, unsigned int *revision);
 void import_kernel_cmdline(int in_qemu, void (*import_kernel_nv)(char *name, int in_qemu));
+int make_dir(const char *path, mode_t mode);
+int restorecon(const char *pathname);
 #endif
diff --git a/libcorkscrew/Android.mk b/libcorkscrew/Android.mk
index 433f93c..aace5f8 100644
--- a/libcorkscrew/Android.mk
+++ b/libcorkscrew/Android.mk
@@ -36,6 +36,12 @@
 	arch-x86/ptrace-x86.c
 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 libgccdemangle
 
diff --git a/libcorkscrew/arch-arm/backtrace-arm.c b/libcorkscrew/arch-arm/backtrace-arm.c
index 5b91164..ff6c192 100644
--- a/libcorkscrew/arch-arm/backtrace-arm.c
+++ b/libcorkscrew/arch-arm/backtrace-arm.c
@@ -62,21 +62,19 @@
 #include <sys/exec_elf.h>
 #include <cutils/log.h>
 
+#if !defined(__BIONIC_HAVE_UCONTEXT_T)
+/* Old versions of the Android <signal.h> didn't define ucontext_t. */
+#include <asm/sigcontext.h> /* Ensure 'struct sigcontext' is defined. */
+
 /* Machine context at the time a signal was raised. */
 typedef struct ucontext {
     uint32_t uc_flags;
     struct ucontext* uc_link;
     stack_t uc_stack;
-    struct sigcontext {
-        uint32_t trap_no;
-        uint32_t error_code;
-        uint32_t oldmask;
-        uint32_t gregs[16];
-        uint32_t arm_cpsr;
-        uint32_t fault_address;
-    } uc_mcontext;
+    struct sigcontext uc_mcontext;
     uint32_t uc_sigmask;
 } ucontext_t;
+#endif /* !__BIONIC_HAVE_UCONTEXT_T */
 
 /* Unwind state. */
 typedef struct {
@@ -560,9 +558,23 @@
     const ucontext_t* uc = (const ucontext_t*)sigcontext;
 
     unwind_state_t state;
-    for (int i = 0; i < 16; i++) {
-        state.gregs[i] = uc->uc_mcontext.gregs[i];
-    }
+
+    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);
diff --git a/libcorkscrew/arch-mips/backtrace-mips.c b/libcorkscrew/arch-mips/backtrace-mips.c
new file mode 100644
index 0000000..07d4a24
--- /dev/null
+++ b/libcorkscrew/arch-mips/backtrace-mips.c
@@ -0,0 +1,194 @@
+/*
+ * 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 <corkscrew/ptrace.h>
+
+#include <stdlib.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/ptrace.h>
+#include <sys/exec_elf.h>
+#include <cutils/log.h>
+
+/* For PTRACE_GETREGS */
+typedef struct {
+    /* FIXME: check this definition */
+    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;
+
+/* Machine context at the time a signal was raised. */
+typedef struct ucontext {
+    /* FIXME: use correct definition */
+    uint32_t sp;
+    uint32_t ra;
+    uint32_t pc;
+} ucontext_t;
+
+/* Unwind state. */
+typedef struct {
+    uint32_t sp;
+    uint32_t ra;
+    uint32_t pc;
+} unwind_state_t;
+
+uintptr_t rewind_pc_arch(const memory_t* memory, uintptr_t pc) {
+    if (pc == 0)
+        return pc;
+    if ((pc & 1) == 0)
+        return pc-8;            /* jal/bal/jalr + branch delay slot */
+    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->pc) : state->pc;
+        backtrace_frame_t* frame;
+        uintptr_t addr;
+        int maxcheck = 1024;
+        int stack_size = 0, ra_offset = 0;
+        bool found_start = false;
+
+        frame = add_backtrace_entry(pc, backtrace, ignore_depth,
+                                    max_depth, &ignored_frames, &returned_frames);
+
+        if (frame)
+            frame->stack_top = state->sp;
+
+        ALOGV("#%d: frame=%p pc=%08x sp=%08x\n", index, frame, frame->absolute_pc, frame->stack_top);
+
+        for (addr = state->pc; maxcheck-- > 0 && !found_start; addr -= 4) {
+            uint32_t op;
+            if (!try_get_word(memory, addr, &op))
+                break;
+
+            // ALOGV("@0x%08x: 0x%08x\n", addr, op);
+            switch (op & 0xffff0000) {
+            case 0x27bd0000: // addiu sp, imm
+                {
+                    // looking for stack being decremented
+                    int32_t immediate = ((((int)op) << 16) >> 16);
+                    if (immediate < 0) {
+                        stack_size = -immediate;
+                        found_start = true;
+                        ALOGV("@0x%08x: found stack adjustment=%d\n", addr, stack_size);
+                    }
+                }
+                break;
+            case 0xafbf0000: // sw ra, imm(sp)
+                ra_offset = ((((int)op) << 16) >> 16);
+                ALOGV("@0x%08x: found ra offset=%d\n", addr, ra_offset);
+                break;
+            case 0x3c1c0000: // lui gp
+                    ALOGV("@0x%08x: found function boundary\n", addr);
+                found_start = true;
+                break;
+            default:
+                break;
+            }
+        }
+
+        if (ra_offset) {
+            uint32_t next_ra;
+            if (!try_get_word(memory, state->sp + ra_offset, &next_ra))
+                break;
+            state->ra = next_ra;
+            ALOGV("New ra: 0x%08x\n", state->ra);
+        }
+
+        if (stack_size) {
+            if (frame)
+                frame->stack_size = stack_size;
+            state->sp += stack_size;
+            ALOGV("New sp: 0x%08x\n", state->sp);
+        }
+
+        if (state->pc == state->ra && stack_size == 0)
+            break;
+
+        if (state->ra == 0)
+            break;
+
+        state->pc = state->ra;
+    }
+
+    ALOGV("returning %d frames\n", 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.sp = uc->sp;
+    state.pc = uc->pc;
+    state.ra = uc->ra;
+
+    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.pc, state.sp, state.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.sp = regs.regs[29];
+    state.ra = regs.regs[31];
+    state.pc = regs.epc;
+
+    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.pc, state.sp, state.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/ptrace-mips.c b/libcorkscrew/arch-mips/ptrace-mips.c
new file mode 100644
index 0000000..f0ea110
--- /dev/null
+++ b/libcorkscrew/arch-mips/ptrace-mips.c
@@ -0,0 +1,28 @@
+/*
+ * 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 <cutils/log.h>
+
+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) {
+}
diff --git a/libcorkscrew/arch-x86/backtrace-x86.c b/libcorkscrew/arch-x86/backtrace-x86.c
index 24fadcb..082f635 100644
--- a/libcorkscrew/arch-x86/backtrace-x86.c
+++ b/libcorkscrew/arch-x86/backtrace-x86.c
@@ -34,37 +34,33 @@
 #include <sys/exec_elf.h>
 #include <cutils/log.h>
 
+#if !defined(__BIONIC_HAVE_UCONTEXT_T)
+/* Old versions of the Android <signal.h> didn't define ucontext_t. */
+
+typedef struct {
+  uint32_t  gregs[32];
+  void*     fpregs;
+  uint32_t  oldmask;
+  uint32_t  cr2;
+} mcontext_t;
+
+enum {
+  REG_GS = 0, REG_FS, REG_ES, REG_DS,
+  REG_EDI, REG_ESI, REG_EBP, REG_ESP,
+  REG_EBX, REG_EDX, REG_ECX, REG_EAX,
+  REG_TRAPNO, REG_ERR, REG_EIP, REG_CS,
+  REG_EFL, REG_UESP, REG_SS
+};
+
 /* Machine context at the time a signal was raised. */
 typedef struct ucontext {
     uint32_t uc_flags;
     struct ucontext* uc_link;
     stack_t uc_stack;
-    struct sigcontext {
-        uint32_t gs;
-        uint32_t fs;
-        uint32_t es;
-        uint32_t ds;
-        uint32_t edi;
-        uint32_t esi;
-        uint32_t ebp;
-        uint32_t esp;
-        uint32_t ebx;
-        uint32_t edx;
-        uint32_t ecx;
-        uint32_t eax;
-        uint32_t trapno;
-        uint32_t err;
-        uint32_t eip;
-        uint32_t cs;
-        uint32_t efl;
-        uint32_t uesp;
-        uint32_t ss;
-        void* fpregs;
-        uint32_t oldmask;
-        uint32_t cr2;
-    } uc_mcontext;
+    mcontext_t uc_mcontext;
     uint32_t uc_sigmask;
 } ucontext_t;
+#endif /* !__BIONIC_HAVE_UCONTEXT_T */
 
 /* Unwind state. */
 typedef struct {
@@ -73,13 +69,13 @@
     uint32_t esp;
 } unwind_state_t;
 
-uintptr_t rewind_pc_arch(const memory_t* memory, uintptr_t pc) {
+uintptr_t rewind_pc_arch(const memory_t* memory __attribute__((unused)), uintptr_t pc) {
     // TODO: Implement for x86.
     return pc;
 }
 
 static ssize_t unwind_backtrace_common(const memory_t* memory,
-        const map_info_t* map_info_list,
+        const map_info_t* map_info_list __attribute__((unused)),
         unwind_state_t* state, backtrace_frame_t* backtrace,
         size_t ignore_depth, size_t max_depth) {
     size_t ignored_frames = 0;
@@ -108,15 +104,15 @@
     return returned_frames;
 }
 
-ssize_t unwind_backtrace_signal_arch(siginfo_t* siginfo, void* sigcontext,
+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.ebp = uc->uc_mcontext.ebp;
-    state.eip = uc->uc_mcontext.eip;
-    state.esp = uc->uc_mcontext.esp;
+    state.ebp = uc->uc_mcontext.gregs[REG_EBP];
+    state.eip = uc->uc_mcontext.gregs[REG_EIP];
+    state.esp = uc->uc_mcontext.gregs[REG_ESP];
 
     memory_t memory;
     init_memory(&memory, map_info_list);
diff --git a/libcorkscrew/arch-x86/ptrace-x86.c b/libcorkscrew/arch-x86/ptrace-x86.c
index f0ea110..07cfd3a 100644
--- a/libcorkscrew/arch-x86/ptrace-x86.c
+++ b/libcorkscrew/arch-x86/ptrace-x86.c
@@ -21,8 +21,11 @@
 
 #include <cutils/log.h>
 
-void load_ptrace_map_info_data_arch(pid_t pid, map_info_t* mi, map_info_data_t* data) {
+void load_ptrace_map_info_data_arch(pid_t pid __attribute__((unused)),
+                                    map_info_t* mi __attribute__((unused)),
+                                    map_info_data_t* data __attribute__((unused))) {
 }
 
-void free_ptrace_map_info_data_arch(map_info_t* mi, map_info_data_t* data) {
+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.c b/libcorkscrew/backtrace.c
index fa21574..e57f428 100644
--- a/libcorkscrew/backtrace.c
+++ b/libcorkscrew/backtrace.c
@@ -99,7 +99,7 @@
     size_t returned_frames;
 } g_unwind_signal_state;
 
-static void unwind_backtrace_thread_signal_handler(int n, siginfo_t* siginfo, void* sigcontext) {
+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,
@@ -282,7 +282,7 @@
     }
 }
 
-void format_backtrace_line(unsigned frameNumber, const backtrace_frame_t* frame,
+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;
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 5c227b6..a9c7981 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -75,7 +75,6 @@
 else
     commonSources += \
         abort_socket.c \
-        mspace.c \
         selector.c \
         tztime.c \
         zygote.c
@@ -129,16 +128,12 @@
 ifeq ($(TARGET_ARCH),arm)
 LOCAL_SRC_FILES += arch-arm/memset32.S
 else  # !arm
-ifeq ($(TARGET_ARCH),sh)
-LOCAL_SRC_FILES += memory.c atomic-android-sh.c
-else  # !sh
 ifeq ($(TARGET_ARCH_VARIANT),x86-atom)
 LOCAL_CFLAGS += -DHAVE_MEMSET16 -DHAVE_MEMSET32
 LOCAL_SRC_FILES += arch-x86/android_memset16.S arch-x86/android_memset32.S memory.c
 else # !x86-atom
 LOCAL_SRC_FILES += memory.c
 endif # !x86-atom
-endif # !sh
 endif # !arm
 
 LOCAL_C_INCLUDES := $(libcutils_c_includes) $(KERNEL_HEADERS)
diff --git a/libcutils/atomic-android-sh.c b/libcutils/atomic-android-sh.c
deleted file mode 100644
index 8bac68a..0000000
--- a/libcutils/atomic-android-sh.c
+++ /dev/null
@@ -1,137 +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 <cutils/atomic.h>
-#ifdef HAVE_WIN32_THREADS
-#include <windows.h>
-#else
-#include <sched.h>
-#endif
-
-/*
- * Note :
- *
- * (1) SuperH does not have CMPXCHG.  It has only TAS for atomic
- *     operations.  It does not seem a good idea to implement CMPXCHG,
- *     with TAS.  So, we choose to implemnt these operations with
- *     posix mutexes.  Please be sure that this might cause performance
- *     problem for Android-SH. Using LL/SC instructions supported in SH-X3,
- *     best performnace would be realized.
- *
- * (2) Mutex initialization problem happens, which is commented for
- *     ARM implementation, in this file above.
- *     We follow the fact that the initializer for mutex is a simple zero
- *     value.
- *
- * (3) These operations are NOT safe for SMP, as there is no currently
- *     no definition for a memory barrier operation.
- */
-
-#include <pthread.h>
-
-#define  SWAP_LOCK_COUNT  32U
-static pthread_mutex_t  _swap_locks[SWAP_LOCK_COUNT];
-
-#define  SWAP_LOCK(addr)   \
-   &_swap_locks[((unsigned)(void*)(addr) >> 3U) % SWAP_LOCK_COUNT]
-
-
-int32_t android_atomic_acquire_load(volatile const int32_t* addr)
-{
-    return *addr;
-}
-
-int32_t android_atomic_release_load(volatile const int32_t* addr)
-{
-    return *addr;
-}
-
-void android_atomic_acquire_store(int32_t value, volatile int32_t* addr) {
-    int32_t oldValue;
-    do {
-        oldValue = *addr;
-    } while (android_atomic_release_cas(oldValue, value, addr));
-}
-
-void android_atomic_release_store(int32_t value, volatile int32_t* addr) {
-    int32_t oldValue;
-    do {
-        oldValue = *addr;
-    } while (android_atomic_release_cas(oldValue, value, addr));
-}
-
-int32_t android_atomic_inc(volatile int32_t* addr) {
-    int32_t oldValue;
-    do {
-        oldValue = *addr;
-    } while (android_atomic_release_cas(oldValue, oldValue+1, addr));
-    return oldValue;
-}
-
-int32_t android_atomic_dec(volatile int32_t* addr) {
-    int32_t oldValue;
-    do {
-        oldValue = *addr;
-    } while (android_atomic_release_cas(oldValue, oldValue-1, addr));
-    return oldValue;
-}
-
-int32_t android_atomic_add(int32_t value, volatile int32_t* addr) {
-    int32_t oldValue;
-    do {
-        oldValue = *addr;
-    } while (android_atomic_release_cas(oldValue, oldValue+value, addr));
-    return oldValue;
-}
-
-int32_t android_atomic_and(int32_t value, volatile int32_t* addr) {
-    int32_t oldValue;
-    do {
-        oldValue = *addr;
-    } while (android_atomic_release_cas(oldValue, oldValue&value, addr));
-    return oldValue;
-}
-
-int32_t android_atomic_or(int32_t value, volatile int32_t* addr) {
-    int32_t oldValue;
-    do {
-        oldValue = *addr;
-    } while (android_atomic_release_cas(oldValue, oldValue|value, addr));
-    return oldValue;
-}
-
-int android_atomic_acquire_cmpxchg(int32_t oldvalue, int32_t newvalue,
-                           volatile int32_t* addr) {
-    return android_atomic_release_cmpxchg(oldValue, newValue, addr);
-}
-
-int android_atomic_release_cmpxchg(int32_t oldvalue, int32_t newvalue,
-                           volatile int32_t* addr) {
-    int result;
-    pthread_mutex_t*  lock = SWAP_LOCK(addr);
-
-    pthread_mutex_lock(lock);
-
-    if (*addr == oldvalue) {
-        *addr  = newvalue;
-        result = 0;
-    } else {
-        result = 1;
-    }
-    pthread_mutex_unlock(lock);
-    return result;
-}
-
diff --git a/libcutils/dlmalloc_stubs.c b/libcutils/dlmalloc_stubs.c
index 1ced147..c327a55 100644
--- a/libcutils/dlmalloc_stubs.c
+++ b/libcutils/dlmalloc_stubs.c
@@ -14,16 +14,22 @@
  * limitations under the License.
  */
 
-/* No-op stubs for functions defined in system/bionic/bionic/dlmalloc.c.
+#include "../../../bionic/libc/bionic/dlmalloc.h"
+#include "cutils/log.h"
+
+/*
+ * 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_walk_free_pages()
+void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*),
+                          void* arg)
 {
+  ALOGW("Called host unimplemented stub: dlmalloc_inspect_all");
 }
 
-void dlmalloc_walk_heap()
+int dlmalloc_trim(size_t unused)
 {
-}
-
-void dlmalloc_trim()
-{
+  ALOGW("Called host unimplemented stub: dlmalloc_trim");
+  return 0;
 }
diff --git a/libcutils/mspace.c b/libcutils/mspace.c
deleted file mode 100644
index 6d3b35c..0000000
--- a/libcutils/mspace.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/* Copyright 2006 The Android Open Source Project */
-
-/* A wrapper file for dlmalloc.c that compiles in the
- * mspace_*() functions, which provide an interface for
- * creating multiple heaps.
- */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <sys/ioctl.h>
-
-#include <cutils/ashmem.h>
-
-/* It's a pain getting the mallinfo stuff to work
- * with Linux, OSX, and klibc, so just turn it off
- * for now.
- * TODO: make mallinfo work
- */
-#define NO_MALLINFO 1
-
-/* Allow setting the maximum heap footprint.
- */
-#define USE_MAX_ALLOWED_FOOTPRINT 1
-
-/* Don't try to trim memory.
- * TODO: support this.
- */
-#define MORECORE_CANNOT_TRIM 1
-
-/* Use mmap()d anonymous memory to guarantee
- * that an mspace is contiguous.
- *
- * create_mspace() won't work right if this is
- * defined, so hide the definition of it and
- * break any users at build time.
- */
-#define USE_CONTIGUOUS_MSPACES 1
-#if USE_CONTIGUOUS_MSPACES
-/* This combination of settings forces sys_alloc()
- * to always use MORECORE().  It won't expect the
- * results to be contiguous, but we'll guarantee
- * that they are.
- */
-#define HAVE_MMAP 0
-#define HAVE_MORECORE 1
-#define MORECORE_CONTIGUOUS 0
-/* m is always the appropriate local when MORECORE() is called. */
-#define MORECORE(S) contiguous_mspace_morecore(m, S)
-#define create_mspace   HIDDEN_create_mspace_HIDDEN
-#define destroy_mspace   HIDDEN_destroy_mspace_HIDDEN
-typedef struct malloc_state *mstate0;
-static void *contiguous_mspace_morecore(mstate0 m, ssize_t nb);
-#endif
-
-#define MSPACES 1
-#define ONLY_MSPACES 1
-#include "../../../bionic/libc/bionic/dlmalloc.c"
-
-#ifndef PAGESIZE
-#define PAGESIZE  mparams.page_size
-#endif
-
-#define ALIGN_UP(p, alignment) \
-    (((uintptr_t)(p) + (alignment)-1) & ~((alignment)-1))
-
-/* A direct copy of dlmalloc_usable_size(),
- * which isn't compiled in when ONLY_MSPACES is set.
- * The mspace parameter isn't actually necessary,
- * but we include it to be consistent with the
- * rest of the mspace_*() functions.
- */
-size_t mspace_usable_size(mspace _unused, const void* mem) {
-  if (mem != 0) {
-    const mchunkptr p = mem2chunk(mem);
-    if (cinuse(p))
-      return chunksize(p) - overhead_for(p);
-  }
-  return 0;
-}
-
-#if USE_CONTIGUOUS_MSPACES
-#include <sys/mman.h>
-#include <limits.h>
-
-#define CONTIG_STATE_MAGIC  0xf00dd00d
-struct mspace_contig_state {
-  unsigned int magic;
-  char *brk;
-  char *top;
-  mspace m;
-};
-
-static void *contiguous_mspace_morecore(mstate m, ssize_t nb) {
-  struct mspace_contig_state *cs;
-  char *oldbrk;
-  const unsigned int pagesize = PAGESIZE;
-
-  cs = (struct mspace_contig_state *)((uintptr_t)m & ~(pagesize-1));
-  assert(cs->magic == CONTIG_STATE_MAGIC);
-  assert(cs->m == m);
-assert(nb >= 0);  //xxx deal with the trim case
-
-  oldbrk = cs->brk;
-  if (nb > 0) {
-    /* Break to the first page boundary that satisfies the request.
-     */
-    char *newbrk = (char *)ALIGN_UP(oldbrk + nb, pagesize);
-    if (newbrk > cs->top)
-      return CMFAIL;
-
-    /* Update the protection on the underlying memory.
-     * Pages we've given to dlmalloc are read/write, and
-     * pages we haven't are not accessable (read or write
-     * will cause a seg fault).
-     */
-    if (mprotect(cs, newbrk - (char *)cs, PROT_READ | PROT_WRITE) < 0)
-      return CMFAIL;
-    if (newbrk != cs->top) {
-      if (mprotect(newbrk, cs->top - newbrk, PROT_NONE) < 0)
-        return CMFAIL;
-    }
-
-    cs->brk = newbrk;
-
-    /* Make sure that dlmalloc will merge this block with the
-     * initial block that was passed to create_mspace_with_base().
-     * We don't care about extern vs. non-extern, so just clear it.
-     */
-    m->seg.sflags &= ~EXTERN_BIT;
-  }
-
-  return oldbrk;
-}
-
-mspace create_contiguous_mspace_with_base(size_t starting_capacity,
-    size_t max_capacity, int locked, void *base) {
-  struct mspace_contig_state *cs;
-  unsigned int pagesize;
-  mstate m;
-
-  init_mparams();
-  pagesize = PAGESIZE;
-  assert(starting_capacity <= max_capacity);
-  assert(((uintptr_t)base & (pagesize-1)) == 0);
-  assert(((uintptr_t)max_capacity & (pagesize-1)) == 0);
-  starting_capacity = (size_t)ALIGN_UP(starting_capacity, pagesize);
-
-  /* Make the first page read/write. dlmalloc needs to use that page.
-   */
-  if (mprotect(base, starting_capacity, PROT_READ | PROT_WRITE) < 0) {
-    goto error;
-  }
-
-  /* Create the mspace, pointing to the memory given.
-   */
-  m = create_mspace_with_base((char *)base + sizeof(*cs), starting_capacity,
-                              locked);
-  if (m == (mspace)0) {
-    goto error;
-  }
-  /* Make sure that m is in the same page as base.
-   */
-  assert(((uintptr_t)m & (uintptr_t)~(pagesize-1)) == (uintptr_t)base);
-  /* Use some space for the information that our MORECORE needs.
-   */
-  cs = (struct mspace_contig_state *)base;
-
-  /* Find out exactly how much of the memory the mspace
-   * is using.
-   */
-  cs->brk = m->seg.base + m->seg.size;
-  cs->top = (char *)base + max_capacity;
-
-  assert((char *)base <= cs->brk);
-  assert(cs->brk <= cs->top);
-  /* Prevent access to the memory we haven't handed out yet.
-   */
-  if (cs->brk != cs->top) {
-    /* mprotect() requires page-aligned arguments, but it's possible
-     * for cs->brk not to be page-aligned at this point.
-     */
-    char *prot_brk = (char *)ALIGN_UP(cs->brk, pagesize);
-    if ((mprotect(base, prot_brk - (char *)base, PROT_READ | PROT_WRITE) < 0) ||
-        (mprotect(prot_brk, cs->top - prot_brk, PROT_NONE) < 0)) {
-      goto error;
-    }
-  }
-
-  cs->m = m;
-  cs->magic = CONTIG_STATE_MAGIC;
-
-  return (mspace)m;
-
-error:
-  return (mspace)0;
-}
-
-
-mspace create_contiguous_mspace_with_name(size_t starting_capacity,
-    size_t max_capacity, int locked, char const *name) {
-  int fd, ret;
-  char buf[ASHMEM_NAME_LEN] = "mspace";
-  void *base;
-  unsigned int pagesize;
-  mstate m;
-
-  if (starting_capacity > max_capacity)
-    return (mspace)0;
-
-  init_mparams();
-  pagesize = PAGESIZE;
-
-  /* Create the anonymous memory that will back the mspace.
-   * This reserves all of the virtual address space we could
-   * ever need.  Physical pages will be mapped as the memory
-   * is touched.
-   *
-   * Align max_capacity to a whole page.
-   */
-  max_capacity = (size_t)ALIGN_UP(max_capacity, pagesize);
-
-  if (name)
-    snprintf(buf, sizeof(buf), "mspace/%s", name);
-  fd = ashmem_create_region(buf, max_capacity);
-  if (fd < 0)
-    return (mspace)0;
-
-  base = mmap(NULL, max_capacity, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
-  close(fd);
-  if (base == MAP_FAILED)
-    return (mspace)0;
-
-  /* Make sure that base is at the beginning of a page.
-   */
-  assert(((uintptr_t)base & (pagesize-1)) == 0);
-
-  m = create_contiguous_mspace_with_base(starting_capacity, max_capacity,
-                                         locked, base);
-  if (m == 0) {
-    munmap(base, max_capacity);
-  }
-  return m;
-}
-
-mspace create_contiguous_mspace(size_t starting_capacity,
-    size_t max_capacity, int locked) {
-  return create_contiguous_mspace_with_name(starting_capacity,
-      max_capacity, locked, NULL);
-}
-
-size_t destroy_contiguous_mspace(mspace msp) {
-  mstate ms = (mstate)msp;
-
-  if (ok_magic(ms)) {
-    struct mspace_contig_state *cs;
-    size_t length;
-    const unsigned int pagesize = PAGESIZE;
-
-    cs = (struct mspace_contig_state *)((uintptr_t)ms & ~(pagesize-1));
-    assert(cs->magic == CONTIG_STATE_MAGIC);
-    assert(cs->m == ms);
-
-    length = cs->top - (char *)cs;
-    if (munmap((char *)cs, length) != 0)
-      return length;
-  }
-  else {
-    USAGE_ERROR_ACTION(ms, ms);
-  }
-  return 0;
-}
-
-void *contiguous_mspace_sbrk0(mspace msp) {
-    struct mspace_contig_state *cs;
-    mstate ms;
-    const unsigned int pagesize = PAGESIZE;
-
-    ms = (mstate)msp;
-    cs = (struct mspace_contig_state *)((uintptr_t)ms & ~(pagesize-1));
-    assert(cs->magic == CONTIG_STATE_MAGIC);
-    assert(cs->m == ms);
-    return cs->brk;
-}
-#endif
diff --git a/libdiskconfig/config_mbr.c b/libdiskconfig/config_mbr.c
index 703484c..b89d382 100644
--- a/libdiskconfig/config_mbr.c
+++ b/libdiskconfig/config_mbr.c
@@ -152,7 +152,7 @@
 
     /* we are going to write the ebr at the current LBA, and then bump the
      * lba counter since that is where the logical data partition will start */
-    item->offset = (*lba) * dinfo->sect_size;
+    item->offset = ((loff_t)(*lba)) * dinfo->sect_size;
     (*lba)++;
 
     ebr = (struct pc_boot_record *) &item->data;
diff --git a/libnetutils/dhcpclient.c b/libnetutils/dhcpclient.c
index b38e258..34500e7 100644
--- a/libnetutils/dhcpclient.c
+++ b/libnetutils/dhcpclient.c
@@ -197,7 +197,11 @@
         }
         switch(opt) {
         case OPT_SUBNET_MASK:
-            if (optlen >= 4) info->prefixLength = ipv4NetmaskToPrefixLength(*((uint32_t*)x));
+            if (optlen >= 4) {
+                in_addr_t mask;
+                memcpy(&mask, x, 4);
+                info->prefixLength = ipv4NetmaskToPrefixLength(mask);
+            }
             break;
         case OPT_GATEWAY:
             if (optlen >= 4) memcpy(&info->gateway, x, 4);
diff --git a/libnetutils/ifc_utils.c b/libnetutils/ifc_utils.c
index 186b98c..f19cb41 100644
--- a/libnetutils/ifc_utils.c
+++ b/libnetutils/ifc_utils.c
@@ -75,9 +75,8 @@
 
 int ipv4NetmaskToPrefixLength(in_addr_t mask)
 {
-    mask = ntohl(mask);
     int prefixLength = 0;
-    uint32_t m = (uint32_t)mask;
+    uint32_t m = (uint32_t)ntohl(mask);
     while (m & 0x80000000) {
         prefixLength++;
         m = m << 1;
@@ -486,7 +485,7 @@
         if(ioctl(ifc_ctl_sock, SIOCGIFNETMASK, &ifr) < 0) {
             *prefixLength = 0;
         } else {
-            *prefixLength = ipv4NetmaskToPrefixLength((int)
+            *prefixLength = ipv4NetmaskToPrefixLength(
                     ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr);
         }
     }
diff --git a/libnetutils/packet.c b/libnetutils/packet.c
index 3ec83fe..be4e0db 100644
--- a/libnetutils/packet.c
+++ b/libnetutils/packet.c
@@ -39,7 +39,7 @@
 
 int fatal();
 
-int open_raw_socket(const char *ifname, uint8_t *hwaddr, int if_index)
+int open_raw_socket(const char *ifname __attribute__((unused)), uint8_t *hwaddr, int if_index)
 {
     int s, flag;
     struct sockaddr_ll bindaddr;
diff --git a/libpixelflinger/Android.mk b/libpixelflinger/Android.mk
index ed2ab5e..1947c2d 100644
--- a/libpixelflinger/Android.mk
+++ b/libpixelflinger/Android.mk
@@ -43,6 +43,11 @@
 PIXELFLINGER_CFLAGS += -fstrict-aliasing -fomit-frame-pointer
 endif
 
+ifeq ($(TARGET_ARCH),mips)
+PIXELFLINGER_SRC_FILES += arch-mips/t32cb16blend.S
+PIXELFLINGER_CFLAGS += -fstrict-aliasing -fomit-frame-pointer
+endif
+
 LOCAL_SHARED_LIBRARIES := libcutils
 
 ifneq ($(TARGET_ARCH),arm)
diff --git a/libpixelflinger/arch-mips/t32cb16blend.S b/libpixelflinger/arch-mips/t32cb16blend.S
new file mode 100644
index 0000000..c911fbb
--- /dev/null
+++ b/libpixelflinger/arch-mips/t32cb16blend.S
@@ -0,0 +1,264 @@
+/* libs/pixelflinger/t32cb16blend.S
+**
+** Copyright 2010, 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.
+*/
+
+#ifdef DEBUG
+#define DBG
+#else
+#define DBG #
+#endif
+
+/*
+ * blend one of 2 16bpp RGB pixels held in dreg selected by shift
+ * with the 32bpp ABGR pixel held in src and store the result in fb
+ *
+ * Assumes that the dreg data is little endian and that
+ * the the second pixel (shift==16) will be merged into
+ * the fb result
+ *
+ * Uses $t0,$t6,$t7,$t8
+ */
+
+#if __mips==32 && __mips_isa_rev>=2
+	.macro pixel dreg src fb shift
+	/*
+	 * sA = s >> 24
+	 * f = 0x100 - (sA + (sA>>7))
+	 */
+DBG	.set	noat
+DBG	rdhwr	$at,$2
+DBG	.set	at
+
+	srl	$t7,\src,24
+	srl	$t6,$t7,7
+	addu	$t7,$t6
+	li	$t6,0x100
+	subu	$t7,$t6,$t7
+
+	/* red */
+	ext	$t8,\dreg,\shift+6+5,5			# dst[\shift:15..11]
+	mul	$t6,$t8,$t7
+	ext	$t0,\dreg,\shift+5,6			# start green extraction dst[\shift:10..5]
+	ext	$t8,\src,3,5				# src[7..3]
+	srl	$t6,8
+	addu	$t8,$t6
+	ins	\fb,$t8,\shift+6+5,5			# dst[\shift:15..11]
+
+        /* green */
+	mul	$t8,$t0,$t7
+	ext	$t0,\dreg,\shift,5			# start blue extraction dst[\shift:4..0]
+	ext	$t6,\src,2+8,6				# src[15..10]
+	srl	$t8,8
+        addu	$t8,$t6
+
+	/* blue */
+	mul	$t0,$t0,$t7
+	ins	\fb,$t8,\shift+5,6			# finish green insertion dst[\shift:10..5]
+	ext	$t6,\src,(3+8+8),5
+	srl	$t8,$t0,8
+	addu	$t8,$t6
+	ins	\fb,$t8,\shift,5
+
+DBG	.set	noat
+DBG	rdhwr	$t8,$2
+DBG	subu	$t8,$at
+DBG	sltu	$at,$t8,$v0
+DBG	movn	$v0,$t8,$at
+DBG	sgtu	$at,$t8,$v1
+DBG	movn	$v1,$t8,$at
+DBG	.set	at
+	.endm
+
+#else
+
+	.macro pixel dreg src fb shift
+	/*
+	 * sA = s >> 24
+	 * f = 0x100 - (sA + (sA>>7))
+	 */
+DBG	.set	push
+DBG	.set	noat
+DBG	.set	mips32r2
+DBG 	rdhwr	$at,$2
+DBG	.set	pop
+
+	srl	$t7,\src,24
+	srl	$t6,$t7,7
+	addu	$t7,$t6
+	li	$t6,0x100
+	subu	$t7,$t6,$t7
+
+	/*
+	 * red
+	 * dR = (d >> (6 + 5)) & 0x1f;
+	 * dR = (f*dR)>>8
+	 * sR = (s >> (   3)) & 0x1f;
+	 * sR += dR
+	 * fb |= sR << 11
+	 */
+	srl	$t8,\dreg,\shift+6+5
+.if \shift==0
+	and     $t8,0x1f
+.endif
+	mul	$t8,$t8,$t7
+	srl	$t6,\src,3
+	and	$t6,0x1f
+	srl	$t8,8
+	addu	$t8,$t6
+.if \shift!=0
+	sll	$t8,\shift+11
+	or	\fb,$t8
+.else
+	sll	\fb,$t8,11
+.endif
+
+        /*
+	 * green
+	 * dG = (d >> 5) & 0x3f
+	 * dG = (f*dG) >> 8
+	 * sG = (s >> ( 8+2))&0x3F;
+	 */
+	srl	$t8,\dreg,\shift+5
+        and	$t8,0x3f
+	mul	$t8,$t8,$t7
+        srl	$t6,\src,8+2
+        and     $t6,0x3f
+	srl	$t8,8
+        addu	$t8,$t6
+	sll	$t8,\shift + 5
+	or	\fb,$t8
+
+	/* blue */
+.if \shift!=0
+	srl	$t8,\dreg,\shift
+	and	$t8,0x1f
+.else
+	and	$t8,\dreg,0x1f
+.endif
+	mul	$t8,$t8,$t7
+	srl	$t6,\src,(8+8+3)
+	and	$t6,0x1f
+	srl	$t8,8
+	addu	$t8,$t6
+.if \shift!=0
+	sll	$t8,\shift
+.endif
+	or	\fb,$t8
+DBG	.set	push
+DBG	.set	noat
+DBG	.set	mips32r2
+DBG	rdhwr	$t8,$2
+DBG	subu	$t8,$at
+DBG	sltu	$at,$t8,$v0
+DBG	movn	$v0,$t8,$at
+DBG	sgtu	$at,$t8,$v1
+DBG	movn	$v1,$t8,$at
+DBG	.set	pop
+	.endm
+#endif
+
+	.text
+	.align
+
+	.global scanline_t32cb16blend_mips
+	.ent	scanline_t32cb16blend_mips
+scanline_t32cb16blend_mips:
+DBG	li	$v0,0xffffffff
+DBG	li	$v1,0
+	/* Align the destination if necessary */
+	and	$t0,$a0,3
+	beqz	$t0,aligned
+
+	/* as long as there is at least one pixel */
+	beqz	$a2,done
+
+	lw	$t4,($a1)
+	addu	$a0,2
+	addu	$a1,4
+	beqz	$t4,1f
+	lhu	$t3,-2($a0)
+	pixel   $t3,$t4,$t1,0
+	sh	$t1,-2($a0)
+1:	subu	$a2,1
+
+aligned:
+	/* Check to see if its worth unrolling the loop */
+	subu	$a2,4
+	bltz	$a2,tail
+
+	/* Process 4 pixels at a time */
+fourpixels:
+	/* 1st pair of pixels */
+	lw	$t4,0($a1)
+	lw	$t5,4($a1)
+	addu	$a0,8
+	addu	$a1,16
+
+	/* both are zero, skip this pair */
+	or	$t3,$t4,$t5
+	beqz	$t3,1f
+
+	/* load the destination */
+	lw	$t3,-8($a0)
+
+	pixel	$t3,$t4,$t1,0
+	pixel	$t3,$t5,$t1,16
+	sw	$t1,-8($a0)
+
+1:
+	/* 2nd pair of pixels */
+	lw	$t4,-8($a1)
+	lw	$t5,-4($a1)
+
+	/* both are zero, skip this pair */
+	or	$t3,$t4,$t5
+	beqz	$t3,1f
+
+	/* load the destination */
+	lw	$t3,-4($a0)
+
+	pixel	$t3,$t4,$t1,0
+	pixel	$t3,$t5,$t1,16
+	sw	$t1,-4($a0)
+
+1:	subu    $a2,4
+	bgtz	$a2,fourpixels
+
+tail:
+	/* the pixel count underran, restore it now */
+	addu	$a2,4
+
+	/* handle the last 0..3 pixels */
+	beqz	$a2,done
+onepixel:
+	lw	$t4,($a1)
+	addu	$a0,2
+	addu	$a1,4
+	beqz	$t4,1f
+	lhu	$t3,-2($a0)
+	pixel   $t3,$t4,$t1,0
+	sh	$t1,-2($a0)
+1:	subu	$a2,1
+	bnez	$a2,onepixel
+done:
+DBG	.set    push
+DBG	.set    mips32r2
+DBG 	rdhwr	$a0,$3
+DBG 	mul	$v0,$a0
+DBG 	mul	$v1,$a0
+DBG	.set    pop
+	j	$ra
+	.end	scanline_t32cb16blend_mips
diff --git a/libpixelflinger/codeflinger/CodeCache.cpp b/libpixelflinger/codeflinger/CodeCache.cpp
index a713feb..60fc771 100644
--- a/libpixelflinger/codeflinger/CodeCache.cpp
+++ b/libpixelflinger/codeflinger/CodeCache.cpp
@@ -23,10 +23,13 @@
 #include <sys/mman.h>
 
 #include <cutils/log.h>
+#include <cutils/ashmem.h>
 #include <cutils/atomic.h>
 
 #include "codeflinger/CodeCache.h"
 
+#define LOG_TAG "CodeCache"
+
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -38,12 +41,72 @@
 
 // ----------------------------------------------------------------------------
 
+// A dlmalloc mspace is used to manage the code cache over a mmaped region.
+#define HAVE_MMAP 0
+#define HAVE_MREMAP 0
+#define HAVE_MORECORE 0
+#define MALLOC_ALIGNMENT 16
+#define MSPACES 1
+#define NO_MALLINFO 1
+#define ONLY_MSPACES 1
+// Custom heap error handling.
+#define PROCEED_ON_ERROR 0
+static void heap_error(const char* msg, const char* function, void* p);
+#define CORRUPTION_ERROR_ACTION(m) \
+    heap_error("HEAP MEMORY CORRUPTION", __FUNCTION__, NULL)
+#define USAGE_ERROR_ACTION(m,p) \
+    heap_error("ARGUMENT IS INVALID HEAP ADDRESS", __FUNCTION__, p)
+
+
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wempty-body"
+#include "../../../../bionic/libc/upstream-dlmalloc/malloc.c"
+#pragma GCC diagnostic warning "-Wstrict-aliasing"
+#pragma GCC diagnostic warning "-Wempty-body"
+
+static void heap_error(const char* msg, const char* function, void* p) {
+    ALOG(LOG_FATAL, LOG_TAG, "@@@ ABORTING: CODE FLINGER: %s IN %s addr=%p",
+         msg, function, p);
+    /* So that we can get a memory dump around p */
+    *((int **) 0xdeadbaad) = (int *) p;
+}
+
+// ----------------------------------------------------------------------------
+
+static void* gExecutableStore = NULL;
+static mspace gMspace = NULL;
+const size_t kMaxCodeCacheCapacity = 1024 * 1024;
+
+static mspace getMspace()
+{
+    if (gExecutableStore == NULL) {
+        int fd = ashmem_create_region("CodeFlinger code cache",
+                                      kMaxCodeCacheCapacity);
+        LOG_ALWAYS_FATAL_IF(fd < 0,
+                            "Creating code cache, ashmem_create_region "
+                            "failed with error '%s'", strerror(errno));
+        gExecutableStore = mmap(NULL, kMaxCodeCacheCapacity,
+                                PROT_READ | PROT_WRITE | PROT_EXEC,
+                                MAP_PRIVATE, fd, 0);
+        LOG_ALWAYS_FATAL_IF(gExecutableStore == NULL,
+                            "Creating code cache, mmap failed with error "
+                            "'%s'", strerror(errno));
+        close(fd);
+        gMspace = create_mspace_with_base(gExecutableStore, kMaxCodeCacheCapacity,
+                                          /*locked=*/ false);
+        mspace_set_footprint_limit(gMspace, kMaxCodeCacheCapacity);
+    }
+    return gMspace;
+}
+
 Assembly::Assembly(size_t size)
     : mCount(1), mSize(0)
 {
     mBase = (uint32_t*)mspace_malloc(getMspace(), size);
+    LOG_ALWAYS_FATAL_IF(mBase == NULL,
+                        "Failed to create Assembly of size %zd in executable "
+                        "store of size %zd", size, kMaxCodeCacheCapacity);
     mSize = size;
-    ensureMbaseExecutable();
 }
 
 Assembly::~Assembly()
@@ -77,31 +140,13 @@
 ssize_t Assembly::resize(size_t newSize)
 {
     mBase = (uint32_t*)mspace_realloc(getMspace(), mBase, newSize);
+    LOG_ALWAYS_FATAL_IF(mBase == NULL,
+                        "Failed to resize Assembly to %zd in code cache "
+                        "of size %zd", newSize, kMaxCodeCacheCapacity);
     mSize = newSize;
-    ensureMbaseExecutable();
     return size();
 }
 
-mspace Assembly::getMspace()
-{
-    static mspace msp = create_contiguous_mspace(2 * 1024, 1024 * 1024, /*locked=*/ false);
-    return msp;
-}
-
-void Assembly::ensureMbaseExecutable()
-{
-    long pagesize = sysconf(_SC_PAGESIZE);
-    long pagemask = ~(pagesize - 1);  // assumes pagesize is a power of 2
-
-    uint32_t* pageStart = (uint32_t*) (((uintptr_t) mBase) & pagemask);
-    size_t adjustedLength = (mBase - pageStart) * sizeof(uint32_t) + mSize;
-
-    if (mBase && mprotect(pageStart, adjustedLength, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) {
-        mspace_free(getMspace(), mBase);
-        mBase = NULL;
-    }
-}
-
 // ----------------------------------------------------------------------------
 
 CodeCache::CodeCache(size_t size)
diff --git a/libpixelflinger/codeflinger/CodeCache.h b/libpixelflinger/codeflinger/CodeCache.h
index aaafd26..54fd69b 100644
--- a/libpixelflinger/codeflinger/CodeCache.h
+++ b/libpixelflinger/codeflinger/CodeCache.h
@@ -22,7 +22,6 @@
 #include <stdint.h>
 #include <pthread.h>
 #include <sys/types.h>
-#include <cutils/mspace.h>
 
 #include "tinyutils/KeyedVector.h"
 #include "tinyutils/smartpointer.h"
@@ -68,9 +67,6 @@
     typedef void    weakref_type;
 
 private:
-    static  mspace  getMspace();
-            void    ensureMbaseExecutable();
-
     mutable int32_t     mCount;
             uint32_t*   mBase;
             size_t      mSize;
diff --git a/libpixelflinger/scanline.cpp b/libpixelflinger/scanline.cpp
index 93440f5..d1f3d96 100644
--- a/libpixelflinger/scanline.cpp
+++ b/libpixelflinger/scanline.cpp
@@ -110,10 +110,14 @@
 static void rect_generic(context_t* c, size_t yc);
 static void rect_memcpy(context_t* c, size_t yc);
 
+#if defined( __arm__)
 extern "C" void scanline_t32cb16blend_arm(uint16_t*, uint32_t*, size_t);
 extern "C" void scanline_t32cb16_arm(uint16_t *dst, uint32_t *src, size_t ct);
 extern "C" void scanline_col32cb16blend_neon(uint16_t *dst, uint32_t *col, size_t ct);
 extern "C" void scanline_col32cb16blend_arm(uint16_t *dst, uint32_t col, size_t ct);
+#elif defined(__mips__)
+extern "C" void scanline_t32cb16blend_mips(uint16_t*, uint32_t*, size_t);
+#endif
 
 // ----------------------------------------------------------------------------
 
@@ -2136,7 +2140,7 @@
 
 void scanline_t32cb16blend(context_t* c)
 {
-#if ((ANDROID_CODEGEN >= ANDROID_CODEGEN_ASM) && defined(__arm__))
+#if ((ANDROID_CODEGEN >= ANDROID_CODEGEN_ASM) && (defined(__arm__) || defined(__mips)))
     int32_t x = c->iterators.xl;
     size_t ct = c->iterators.xr - x;
     int32_t y = c->iterators.y;
@@ -2148,8 +2152,12 @@
     const int32_t v = (c->state.texture[0].shade.it0>>16) + y;
     uint32_t *src = reinterpret_cast<uint32_t*>(tex->data)+(u+(tex->stride*v));
 
+#ifdef __arm__
     scanline_t32cb16blend_arm(dst, src, ct);
 #else
+    scanline_t32cb16blend_mips(dst, src, ct);
+#endif
+#else
     dst_iterator16  di(c);
     horz_iterator32  hi(c);
     blender_32to16  bl(c);
diff --git a/libsparse/Android.mk b/libsparse/Android.mk
index 69b52c3..9025cc0 100644
--- a/libsparse/Android.mk
+++ b/libsparse/Android.mk
@@ -10,92 +10,90 @@
         sparse_err.c \
         sparse_read.c
 
-include $(CLEAR_VARS)
 
+include $(CLEAR_VARS)
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_SRC_FILES := $(libsparse_src_files)
-LOCAL_MODULE := libsparse
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libsparse_host
 LOCAL_STATIC_LIBRARIES := libz
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/include external/zlib
-
 include $(BUILD_HOST_STATIC_LIBRARY)
 
-include $(CLEAR_VARS)
 
+include $(CLEAR_VARS)
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_SRC_FILES := $(libsparse_src_files)
 LOCAL_MODULE := libsparse
-LOCAL_MODULE_TAGS := optional
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/include external/zlib
-LOCAL_SHARED_LIBRARIES := libz
-
+LOCAL_SHARED_LIBRARIES := \
+    libz
 include $(BUILD_SHARED_LIBRARY)
 
-include $(CLEAR_VARS)
 
+include $(CLEAR_VARS)
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_SRC_FILES := $(libsparse_src_files)
-LOCAL_MODULE := libsparse
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libsparse_static
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/include external/zlib
 LOCAL_STATIC_LIBRARIES := libz
-
 include $(BUILD_STATIC_LIBRARY)
 
-include $(CLEAR_VARS)
 
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := simg2img.c \
+	sparse_crc32.c
+LOCAL_MODULE := simg2img_host
+# Need a unique module name, but exe should still be called simg2img
+LOCAL_MODULE_STEM := simg2img
+LOCAL_STATIC_LIBRARIES := \
+    libsparse_host \
+    libz
+include $(BUILD_HOST_EXECUTABLE)
+
+
+include $(CLEAR_VARS)
 LOCAL_SRC_FILES := simg2img.c \
 	sparse_crc32.c
 LOCAL_MODULE := simg2img
-LOCAL_MODULE_TAGS := debug
-LOCAL_STATIC_LIBRARIES := libsparse libz
-
-include $(BUILD_HOST_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := simg2img.c \
-	sparse_crc32.c
-LOCAL_MODULE := simg2img
-LOCAL_MODULE_TAGS := optional
-LOCAL_STATIC_LIBRARIES := libsparse libz
-
+LOCAL_STATIC_LIBRARIES := \
+    libsparse_static \
+    libz
 include $(BUILD_EXECUTABLE)
 
+
 include $(CLEAR_VARS)
-
 LOCAL_SRC_FILES := img2simg.c
-LOCAL_MODULE := img2simg
-LOCAL_MODULE_TAGS := debug
-LOCAL_STATIC_LIBRARIES := libsparse libz
-
+LOCAL_MODULE := img2simg_host
+# Need a unique module name, but exe should still be called simg2img
+LOCAL_MODULE_STEM := img2simg
+LOCAL_STATIC_LIBRARIES := \
+    libsparse_host \
+    libz
 include $(BUILD_HOST_EXECUTABLE)
 
-include $(CLEAR_VARS)
 
+include $(CLEAR_VARS)
 LOCAL_SRC_FILES := img2simg.c
 LOCAL_MODULE := img2simg
-LOCAL_MODULE_TAGS := optional
-LOCAL_STATIC_LIBRARIES := libsparse libz
-
+LOCAL_STATIC_LIBRARIES := \
+    libsparse_static \
+    libz
 include $(BUILD_EXECUTABLE)
 
-include $(CLEAR_VARS)
 
+include $(CLEAR_VARS)
 LOCAL_SRC_FILES := simg2simg.c
 LOCAL_MODULE := simg2simg
-LOCAL_MODULE_TAGS := debug
-LOCAL_STATIC_LIBRARIES := libsparse libz
-
+LOCAL_STATIC_LIBRARIES := \
+    libsparse_host \
+    libz
 include $(BUILD_HOST_EXECUTABLE)
 
-include $(CLEAR_VARS)
 
+include $(CLEAR_VARS)
 LOCAL_MODULE := simg_dump.py
-LOCAL_MODULE_TAGS := debug
 LOCAL_SRC_FILES := simg_dump.py
 LOCAL_MODULE_CLASS := EXECUTABLES
 LOCAL_IS_HOST_MODULE := true
-
 include $(BUILD_PREBUILT)
+
diff --git a/libsparse/sparse.c b/libsparse/sparse.c
index 189b4c0..741e8c6 100644
--- a/libsparse/sparse.c
+++ b/libsparse/sparse.c
@@ -139,7 +139,7 @@
 				DIV_ROUND_UP(backed_block_len(bb), s->block_size);
 	}
 
-	pad = s->len - last_block * s->block_size;
+	pad = s->len - (int64_t)last_block * s->block_size;
 	assert(pad >= 0);
 	if (pad > 0) {
 		write_skip_chunk(out, pad);
diff --git a/libsuspend/autosuspend_wakeup_count.c b/libsuspend/autosuspend_wakeup_count.c
index b038e20..a88e677 100644
--- a/libsuspend/autosuspend_wakeup_count.c
+++ b/libsuspend/autosuspend_wakeup_count.c
@@ -38,7 +38,7 @@
 static sem_t suspend_lockout;
 static const char *sleep_state = "mem";
 
-static void *suspend_thread_func(void *arg)
+static void *suspend_thread_func(void *arg __attribute__((unused)))
 {
     char buf[80];
     char wakeup_count[20];
diff --git a/libsync/sync_test.c b/libsync/sync_test.c
index a75f671..386747a 100644
--- a/libsync/sync_test.c
+++ b/libsync/sync_test.c
@@ -72,7 +72,7 @@
     return NULL;
 }
 
-int main(int argc, char *argv[])
+int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
 {
     struct sync_thread_data sync_data[4];
     pthread_t threads[4];
diff --git a/libzipfile/centraldir.c b/libzipfile/centraldir.c
index 0e264a3..911e2b9 100644
--- a/libzipfile/centraldir.c
+++ b/libzipfile/centraldir.c
@@ -192,7 +192,7 @@
 

     // too small to be a ZIP archive?

     if (bufsize < EOCD_LEN) {

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

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

         goto bail;

     }

 

diff --git a/libzipfile/test_zipfile.c b/libzipfile/test_zipfile.c
index 40840ec..1aaa913 100644
--- a/libzipfile/test_zipfile.c
+++ b/libzipfile/test_zipfile.c
@@ -1,5 +1,5 @@
 #include <zipfile/zipfile.h>

-

+#include <string.h>

 #include <stdio.h>

 #include <stdlib.h>

 

@@ -55,6 +55,8 @@
 

     switch (what)

     {

+        case HUH:

+            break;

         case LIST:

             dump_zipfile(stdout, zip);

             break;

diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index b71ce86..d3b5ed0 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -101,7 +101,7 @@
 
 static int openLogFile (const char *pathname)
 {
-    return open(g_outputFileName, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
+    return open(pathname, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
 }
 
 static void rotateLogs()
diff --git a/mkbootimg/mkbootimg.c b/mkbootimg/mkbootimg.c
index a94cb9c..2c32ce3 100644
--- a/mkbootimg/mkbootimg.c
+++ b/mkbootimg/mkbootimg.c
@@ -109,18 +109,17 @@
     int fd;
     SHA_CTX ctx;
     uint8_t* sha;
+    unsigned base           = 0x10000000;
+    unsigned kernel_offset  = 0x00008000;
+    unsigned ramdisk_offset = 0x01000000;
+    unsigned second_offset  = 0x00f00000;
+    unsigned tags_offset    = 0x00000100;
 
     argc--;
     argv++;
 
     memset(&hdr, 0, sizeof(hdr));
 
-        /* default load addresses */
-    hdr.kernel_addr =  0x10008000;
-    hdr.ramdisk_addr = 0x11000000;
-    hdr.second_addr =  0x10F00000;
-    hdr.tags_addr =    0x10000100;
-
     while(argc > 0){
         char *arg = argv[0];
         char *val = argv[1];
@@ -140,11 +139,15 @@
         } else if(!strcmp(arg, "--cmdline")) {
             cmdline = val;
         } else if(!strcmp(arg, "--base")) {
-            unsigned base = strtoul(val, 0, 16);
-            hdr.kernel_addr =  base + 0x00008000;
-            hdr.ramdisk_addr = base + 0x01000000;
-            hdr.second_addr =  base + 0x00F00000;
-            hdr.tags_addr =    base + 0x00000100;
+            base = strtoul(val, 0, 16);
+        } else if(!strcmp(arg, "--kernel_offset")) {
+            kernel_offset = strtoul(val, 0, 16);
+        } else if(!strcmp(arg, "--ramdisk_offset")) {
+            ramdisk_offset = strtoul(val, 0, 16);
+        } else if(!strcmp(arg, "--second_offset")) {
+            second_offset = strtoul(val, 0, 16);
+        } else if(!strcmp(arg, "--tags_offset")) {
+            tags_offset = strtoul(val, 0, 16);
         } else if(!strcmp(arg, "--board")) {
             board = val;
         } else if(!strcmp(arg,"--pagesize")) {
@@ -159,6 +162,10 @@
     }
     hdr.page_size = pagesize;
 
+    hdr.kernel_addr =  base + kernel_offset;
+    hdr.ramdisk_addr = base + ramdisk_offset;
+    hdr.second_addr =  base + second_offset;
+    hdr.tags_addr =    base + tags_offset;
 
     if(bootimg == 0) {
         fprintf(stderr,"error: no output filename specified\n");
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index e62c3ea..64ff522 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -15,6 +15,10 @@
 copy_from += etc/vold.fstab
 endif
 
+ifeq ($(TARGET_PRODUCT),full_mips)
+copy_from += etc/vold.fstab
+endif
+
 # the /system/etc/init.goldfish.sh is needed to enable emulator support
 # in the system image. In theory, we don't need these for -user builds
 # which are device-specific. However, these builds require at the moment
diff --git a/rootdir/etc/init.goldfish.rc b/rootdir/etc/init.goldfish.rc
index 83b7f8a..cde9dee 100644
--- a/rootdir/etc/init.goldfish.rc
+++ b/rootdir/etc/init.goldfish.rc
@@ -5,6 +5,10 @@
     symlink /mnt/sdcard /sdcard
 
 on boot
+    setsebool in_qemu=1
+    restorecon /sys/qemu_trace/process_name
+    restorecon /sys/qemu_trace/state
+    restorecon /sys/qemu_trace/symbol
     setprop ARGH ARGH
     setprop net.eth0.gw 10.0.2.2
     setprop net.eth0.dns1 10.0.2.3
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 334bff0..fb52486 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -12,6 +12,10 @@
     # Set init and its forked children's oom_adj.
     write /proc/1/oom_adj -16
 
+    # Set the security context for the init process.
+    # This should occur before anything else (e.g. ueventd) is started.
+    setcon u:r:init:s0
+
     start ueventd
 
 # create mountpoints
@@ -128,10 +132,14 @@
     # We chown/chmod /cache again so because mount is run as root + defaults
     chown system cache /cache
     chmod 0770 /cache
+    # We restorecon /cache in case the cache partition has been reset.
+    restorecon /cache
 
     # This may have been created by the recovery system with odd permissions
     chown system cache /cache/recovery
     chmod 0770 /cache/recovery
+    # This may have been created by the recovery system with the wrong context.
+    restorecon /cache/recovery
 
     #change permissions on vmallocinfo so we can grab it from bugreports
     chown root log /proc/vmallocinfo
@@ -150,6 +158,8 @@
     # We chown/chmod /data again so because mount is run as root + defaults
     chown system system /data
     chmod 0771 /data
+    # We restorecon /data in case the userdata partition has been reset.
+    restorecon /data
 
     # Create dump dir and collect dumps.
     # Do this before we mount cache so eventually we can use cache for
@@ -347,6 +357,11 @@
 service ueventd /sbin/ueventd
     class core
     critical
+    seclabel u:r:ueventd:s0
+
+on property:selinux.reload_policy=1
+    restart ueventd
+    restart installd
 
 service console /system/bin/sh
     class core
@@ -362,6 +377,7 @@
 service adbd /sbin/adbd
     class core
     disabled
+    seclabel u:r:adbd:s0
 
 # adbd on at boot in emulator
 on property:ro.kernel.qemu=1
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 07624c4..c1fca00 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -18,6 +18,9 @@
 # gpu driver for adreno200 is globally accessible
 /dev/kgsl                 0666   root       root
 
+# kms driver for drm based gpu
+/dev/dri/*                0666   root       graphics
+
 # these should not be world writable
 /dev/diag                 0660   radio      radio
 /dev/diag_arm9            0660   radio      radio
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index a95513c..ad2f2ab 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -115,9 +115,6 @@
     char rootpath[1024];
 };
 
-static unsigned uid = -1;
-static unsigned gid = -1;
-
 #define PATH_BUFFER_SIZE 1024
 
 #define NO_CASE_SENSITIVE_MATCH 0
@@ -954,7 +951,7 @@
 
 static int usage()
 {
-    ERROR("usage: sdcard [-l -f] <path> <uid> <gid>\n\n\t-l force file names to lower case when creating new files\n\t-f fix up file system before starting (repairs bad file name case and group ownership)\n");
+    ERROR("usage: sdcard <path> <uid> <gid>\n");
     return -1;
 }
 
@@ -966,28 +963,30 @@
     int res;
     const char *path = NULL;
     int i;
+    unsigned int uid = 0;
+    unsigned int gid = 0;
 
-    for (i = 1; i < argc; i++) {
-        char* arg = argv[i];
-        if (!path)
-            path = arg;
-        else if (uid == -1)
-            uid = strtoul(arg, 0, 10);
-        else if (gid == -1)
-            gid = strtoul(arg, 0, 10);
-        else {
-            ERROR("too many arguments\n");
-            return usage();
-        }
+
+    if (argc != 4) {
+      return usage();
     }
 
-    if (!path) {
-        ERROR("no path specified\n");
-        return usage();
+    path = argv[1];
+
+    char* endptr = NULL;
+    errno = 0;
+    uid = strtoul(argv[2], &endptr, 10);
+    if (*endptr != '\0' || errno != 0) {
+      ERROR("Invalid uid");
+      return usage();
     }
-    if (uid <= 0 || gid <= 0) {
-        ERROR("uid and gid must be nonzero\n");
-        return usage();
+
+    endptr = NULL;
+    errno = 0;
+    gid = strtoul(argv[3], &endptr, 10);
+    if (*endptr != '\0' || errno != 0) {
+      ERROR("Invalid gid");
+      return usage();
     }
 
         /* cleanup from previous instance, if necessary */
diff --git a/sh/eval.c b/sh/eval.c
index 9acfd64..4eb7ded 100644
--- a/sh/eval.c
+++ b/sh/eval.c
@@ -687,14 +687,14 @@
 	struct cmdentry cmdentry;
 	struct job *jp;
 	struct jmploc jmploc;
-	struct jmploc *volatile savehandler;
+	struct jmploc *volatile savehandler = 0;
 	char *volatile savecmdname;
 	volatile struct shparam saveparam;
 	struct localvar *volatile savelocalvars;
 	volatile int e;
 	char *lastarg;
 	const char *path = pathval();
-	volatile int temp_path;
+	volatile int temp_path = 0;
 #if __GNUC__
 	/* Avoid longjmp clobbering */
 	(void) &argv;
diff --git a/toolbox/kill.c b/toolbox/kill.c
index b79805f..fa2f649 100644
--- a/toolbox/kill.c
+++ b/toolbox/kill.c
@@ -42,7 +42,9 @@
     /* non-SUS signals */
     _SIG(IO),
     _SIG(PWR),
+#ifdef SIGSTKFLT
     _SIG(STKFLT),
+#endif
     _SIG(WINCH),
 #undef _SIG
 };
diff --git a/toolbox/restorecon.c b/toolbox/restorecon.c
index 5ef0ef1..f9f604f 100644
--- a/toolbox/restorecon.c
+++ b/toolbox/restorecon.c
@@ -7,8 +7,7 @@
 #include <fts.h>
 #include <selinux/selinux.h>
 #include <selinux/label.h>
-
-#define FCPATH "/file_contexts"
+#include <selinux/android.h>
 
 static struct selabel_handle *sehandle;
 static const char *progname;
@@ -17,7 +16,7 @@
 
 static void usage(void)
 {
-    fprintf(stderr, "usage:  %s [-f file_contexts] [-nrRv] pathname...\n", progname);
+    fprintf(stderr, "usage:  %s [-nrRv] pathname...\n", progname);
     exit(1);
 }
 
@@ -54,21 +53,16 @@
 
 int restorecon_main(int argc, char **argv)
 {
-    struct selinux_opt seopts[] = {
-        { SELABEL_OPT_PATH, FCPATH }
-    };
     int ch, recurse = 0, ftsflags = FTS_PHYSICAL;
+    int i = 0;
 
     progname = argv[0];
 
     do {
-        ch = getopt(argc, argv, "f:nrRv");
+        ch = getopt(argc, argv, "nrRv");
         if (ch == EOF)
             break;
         switch (ch) {
-        case 'f':
-            seopts[0].value = optarg;
-            break;
         case 'n':
             nochange = 1;
             break;
@@ -89,9 +83,10 @@
     if (!argc)
         usage();
 
-    sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);
+    sehandle = selinux_android_file_context_handle();
+
     if (!sehandle) {
-        fprintf(stderr, "Could not load file contexts from %s:  %s\n", seopts[0].value,
+        fprintf(stderr, "Could not load file_contexts:  %s\n",
                 strerror(errno));
         return -1;
     }
diff --git a/toolbox/setenforce.c b/toolbox/setenforce.c
index 1b0ea5c..444073d 100644
--- a/toolbox/setenforce.c
+++ b/toolbox/setenforce.c
@@ -7,7 +7,7 @@
 #include <errno.h>
 #include <selinux/selinux.h>
 
-void usage(const char *progname)
+static void usage(const char *progname)
 {
     fprintf(stderr, "usage:  %s [ Enforcing | Permissive | 1 | 0 ]\n",
             progname);
diff --git a/toolbox/vmstat.c b/toolbox/vmstat.c
index 600f136..4086ed0 100644
--- a/toolbox/vmstat.c
+++ b/toolbox/vmstat.c
@@ -75,7 +75,7 @@
     int toggle, count;
     int i;
 
-    iterations = 0;
+    iterations = -1;
     delay = 1;
     header_interval = 20;
 
@@ -119,7 +119,7 @@
     if (!header_interval)
         print_header();
     read_state(&s[1 - toggle]);
-    while ((iterations == 0) || (iterations-- > 0)) {
+    while ((iterations < 0) || (iterations-- > 0)) {
         sleep(delay);
         read_state(&s[toggle]);
         if (header_interval) {