am 4089cda0: Merge "NativeBridge: Tighten security on libnativebridge" into lmp-dev

* commit '4089cda0ae73e71adb787e595c747846e30730ee':
  NativeBridge: Tighten security on libnativebridge
diff --git a/adb/Android.mk b/adb/Android.mk
index 44c3215..bba5365 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -24,6 +24,7 @@
   USB_SRCS := usb_osx.c
   EXTRA_SRCS := get_my_path_darwin.c
   LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon
+  LOCAL_CFLAGS += -Wno-sizeof-pointer-memaccess -Wno-unused-parameter
 endif
 
 ifeq ($(HOST_OS),freebsd)
diff --git a/adb/usb_osx.c b/adb/usb_osx.c
index 45ce444..5efb23b 100644
--- a/adb/usb_osx.c
+++ b/adb/usb_osx.c
@@ -197,7 +197,8 @@
         kr = (*dev)->GetDeviceProduct(dev, &product);
         kr = (*dev)->GetLocationID(dev, &locationId);
         if (kr == 0) {
-            snprintf(devpathBuf, sizeof(devpathBuf), "usb:%lX", locationId);
+            snprintf(devpathBuf, sizeof(devpathBuf), "usb:%" PRIu32 "X",
+	             (unsigned int)locationId);
             devpath = devpathBuf;
         }
         kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex);
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index 957e5db..6288155 100755
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -164,6 +164,8 @@
 #define VENDOR_ID_SK_TELESYS    0x1F53
 // Smartisan's USB Vendor ID
 #define VENDOR_ID_SMARTISAN     0x29a9
+// Sonim Tech's USB Vendor ID
+#define VENDOR_ID_SONIM_TECH    0x1d9c
 // Sony's USB Vendor ID
 #define VENDOR_ID_SONY          0x054C
 // Sony Ericsson's USB Vendor ID
@@ -261,6 +263,7 @@
     VENDOR_ID_SHARP,
     VENDOR_ID_SK_TELESYS,
     VENDOR_ID_SMARTISAN,
+    VENDOR_ID_SONIM_TECH,
     VENDOR_ID_SONY,
     VENDOR_ID_SONY_ERICSSON,
     VENDOR_ID_T_AND_A,
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 61805c9..03d7e49 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -30,6 +30,8 @@
 #include <sys/stat.h>
 #include <sys/poll.h>
 
+#include <selinux/android.h>
+
 #include <log/logger.h>
 
 #include <cutils/sockets.h>
@@ -124,6 +126,53 @@
   return fields == 7 ? 0 : -1;
 }
 
+static int selinux_enabled;
+
+/*
+ * Corresponds with debugger_action_t enum type in
+ * include/cutils/debugger.h.
+ */
+static const char *debuggerd_perms[] = {
+  NULL, /* crash is only used on self, no check applied */
+  "dump_tombstone",
+  "dump_backtrace"
+};
+
+static bool selinux_action_allowed(int s, pid_t tid, debugger_action_t action)
+{
+  char *scon = NULL, *tcon = NULL;
+  const char *tclass = "debuggerd";
+  const char *perm;
+  bool allowed = false;
+
+  if (selinux_enabled <= 0)
+    return true;
+
+  if (action <= 0 || action >= (sizeof(debuggerd_perms)/sizeof(debuggerd_perms[0]))) {
+    ALOGE("SELinux:  No permission defined for debugger action %d", action);
+    return false;
+  }
+
+  perm = debuggerd_perms[action];
+
+  if (getpeercon(s, &scon) < 0) {
+    ALOGE("Cannot get peer context from socket\n");
+    goto out;
+  }
+
+  if (getpidcon(tid, &tcon) < 0) {
+    ALOGE("Cannot get context for tid %d\n", tid);
+    goto out;
+  }
+
+  allowed = (selinux_check_access(scon, tcon, tclass, perm, NULL) == 0);
+
+out:
+   freecon(scon);
+   freecon(tcon);
+   return allowed;
+}
+
 static int read_request(int fd, debugger_request_t* out_request) {
   ucred cr;
   socklen_t len = sizeof(cr);
@@ -186,6 +235,9 @@
       ALOGE("tid %d does not exist. ignoring explicit dump request\n", out_request->tid);
       return -1;
     }
+
+    if (!selinux_action_allowed(fd, out_request->tid, out_request->action))
+      return -1;
   } else {
     // No one else is allowed to dump arbitrary processes.
     return -1;
@@ -434,7 +486,11 @@
 }
 
 int main(int argc, char** argv) {
+  union selinux_callback cb;
   if (argc == 1) {
+    selinux_enabled = is_selinux_enabled();
+    cb.func_log = selinux_log_callback;
+    selinux_set_callback(SELINUX_CB_LOG, cb);
     return do_server();
   }
 
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 252db6c..d212b2c 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -32,6 +32,7 @@
   LOCAL_SRC_FILES += usb_osx.c util_osx.c
   LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit \
 	-framework Carbon
+  LOCAL_CFLAGS += -Wno-unused-parameter
 endif
 
 ifeq ($(HOST_OS),windows)
diff --git a/fastboot/usb_osx.c b/fastboot/usb_osx.c
index 0f55e0d..0b6c515 100644
--- a/fastboot/usb_osx.c
+++ b/fastboot/usb_osx.c
@@ -328,7 +328,8 @@
         ERR("GetLocationId");
         goto error;
     }
-    snprintf(handle->info.device_path, sizeof(handle->info.device_path), "usb:%lX", locationId);
+    snprintf(handle->info.device_path, sizeof(handle->info.device_path),
+             "usb:%" PRIu32 "X", (unsigned int)locationId);
 
     kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex);
 
diff --git a/include/cutils/atomic-arm64.h b/include/cutils/atomic-arm64.h
index 4562ad0..ba5a218 100644
--- a/include/cutils/atomic-arm64.h
+++ b/include/cutils/atomic-arm64.h
@@ -46,18 +46,6 @@
     __asm__ __volatile__ ("" : : : "memory");
 }
 
-#if ANDROID_SMP == 0
-extern ANDROID_ATOMIC_INLINE
-void android_memory_barrier(void)
-{
-    android_compiler_barrier();
-}
-extern ANDROID_ATOMIC_INLINE
-void android_memory_store_barrier(void)
-{
-    android_compiler_barrier();
-}
-#else
 extern ANDROID_ATOMIC_INLINE
 void android_memory_barrier(void)
 {
@@ -68,7 +56,6 @@
 {
     __asm__ __volatile__ ("dmb ishst" : : : "memory");
 }
-#endif
 
 extern ANDROID_ATOMIC_INLINE
 int32_t android_atomic_acquire_load(volatile const int32_t *ptr)
diff --git a/include/cutils/atomic-mips64.h b/include/cutils/atomic-mips64.h
index 99bbe3a..6215621 100644
--- a/include/cutils/atomic-mips64.h
+++ b/include/cutils/atomic-mips64.h
@@ -28,16 +28,6 @@
     __asm__ __volatile__ ("" : : : "memory");
 }
 
-#if ANDROID_SMP == 0
-extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
-{
-    android_compiler_barrier();
-}
-extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
-{
-    android_compiler_barrier();
-}
-#else
 extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
 {
     __asm__ __volatile__ ("sync" : : : "memory");
@@ -46,7 +36,6 @@
 {
     __asm__ __volatile__ ("sync" : : : "memory");
 }
-#endif
 
 extern ANDROID_ATOMIC_INLINE
 int32_t android_atomic_acquire_load(volatile const int32_t *ptr)
diff --git a/include/cutils/atomic-x86_64.h b/include/cutils/atomic-x86_64.h
index 5b5c203..025ba19 100644
--- a/include/cutils/atomic-x86_64.h
+++ b/include/cutils/atomic-x86_64.h
@@ -41,18 +41,6 @@
     __asm__ __volatile__ ("" : : : "memory");
 }
 
-#if ANDROID_SMP == 0
-extern ANDROID_ATOMIC_INLINE
-void android_memory_barrier(void)
-{
-    android_compiler_barrier();
-}
-extern ANDROID_ATOMIC_INLINE
-void android_memory_store_barrier(void)
-{
-    android_compiler_barrier();
-}
-#else
 extern ANDROID_ATOMIC_INLINE
 void android_memory_barrier(void)
 {
@@ -63,7 +51,6 @@
 {
     android_compiler_barrier();
 }
-#endif
 
 extern ANDROID_ATOMIC_INLINE
 int32_t android_atomic_acquire_load(volatile const int32_t *ptr)
diff --git a/include/cutils/open_memstream.h b/include/cutils/open_memstream.h
index b7998be..c1a81eb 100644
--- a/include/cutils/open_memstream.h
+++ b/include/cutils/open_memstream.h
@@ -19,7 +19,7 @@
 
 #include <stdio.h>
 
-#ifndef HAVE_OPEN_MEMSTREAM
+#if defined(__APPLE__)
 
 #ifdef __cplusplus
 extern "C" {
@@ -31,6 +31,6 @@
 }
 #endif
 
-#endif /*!HAVE_OPEN_MEMSTREAM*/
+#endif /* __APPLE__ */
 
 #endif /*__CUTILS_OPEN_MEMSTREAM_H__*/
diff --git a/include/private/pixelflinger/ggl_fixed.h b/include/private/pixelflinger/ggl_fixed.h
index d0493f3..787f620 100644
--- a/include/private/pixelflinger/ggl_fixed.h
+++ b/include/private/pixelflinger/ggl_fixed.h
@@ -190,7 +190,7 @@
         );
     return res;
 }
-#elif defined(__mips__)
+#elif defined(__mips__) && __mips_isa_rev < 6
 
 /*inline MIPS implementations*/
 inline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) CONST;
diff --git a/include/utils/AndroidThreads.h b/include/utils/AndroidThreads.h
index 4eee14d..3c640b6 100644
--- a/include/utils/AndroidThreads.h
+++ b/include/utils/AndroidThreads.h
@@ -73,9 +73,6 @@
 // ------------------------------------------------------------------
 // Extra functions working with raw pids.
 
-// Get pid for the current thread.
-extern pid_t androidGetTid();
-
 #ifdef HAVE_ANDROID_OS
 // Change the priority AND scheduling group of a particular thread.  The priority
 // should be one of the ANDROID_PRIORITY constants.  Returns INVALID_OPERATION
diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h
index 8e15c19..eac6a78 100644
--- a/include/utils/RefBase.h
+++ b/include/utils/RefBase.h
@@ -491,7 +491,8 @@
                 TYPE::renameRefId(d[i].get(), &s[i], &d[i]);
             }
         public:
-            Renamer(sp<TYPE>* d, sp<TYPE> const* s) : s(s), d(d) { }
+            Renamer(sp<TYPE>* d, sp<TYPE> const* s) : d(d), s(s) { }
+            virtual ~Renamer() { }
         };
 
         memmove(d, s, n*sizeof(sp<TYPE>));
@@ -510,7 +511,8 @@
                 TYPE::renameRefId(d[i].get_refs(), &s[i], &d[i]);
             }
         public:
-            Renamer(wp<TYPE>* d, wp<TYPE> const* s) : s(s), d(d) { }
+            Renamer(wp<TYPE>* d, wp<TYPE> const* s) : d(d), s(s) { }
+            virtual ~Renamer() { }
         };
 
         memmove(d, s, n*sizeof(wp<TYPE>));
diff --git a/include/utils/Thread.h b/include/utils/Thread.h
index df30611..c867e95 100644
--- a/include/utils/Thread.h
+++ b/include/utils/Thread.h
@@ -71,8 +71,8 @@
             bool        isRunning() const;
 
 #ifdef HAVE_ANDROID_OS
-    // Return the thread's kernel ID, same as the thread itself calling gettid() or
-    // androidGetTid(), or -1 if the thread is not running.
+    // Return the thread's kernel ID, same as the thread itself calling gettid(),
+    // or -1 if the thread is not running.
             pid_t       getTid() const;
 #endif
 
diff --git a/include/ziparchive/zip_archive.h b/include/ziparchive/zip_archive.h
index 1877494..7da6e84 100644
--- a/include/ziparchive/zip_archive.h
+++ b/include/ziparchive/zip_archive.h
@@ -21,6 +21,7 @@
 #define LIBZIPARCHIVE_ZIPARCHIVE_H_
 
 #include <stdint.h>
+#include <string.h>
 #include <sys/types.h>
 #include <utils/Compat.h>
 
@@ -33,8 +34,16 @@
 };
 
 struct ZipEntryName {
-  const char* name;
+  const uint8_t* name;
   uint16_t name_length;
+
+  ZipEntryName() {}
+
+  /*
+   * entry_name has to be an c-style string with only ASCII characters.
+   */
+  explicit ZipEntryName(const char* entry_name)
+      : name(reinterpret_cast<const uint8_t*>(entry_name)), name_length(strlen(entry_name)) {}
 };
 
 /*
@@ -124,24 +133,24 @@
  * and length, a call to VerifyCrcAndLengths must be made after entry data
  * has been processed.
  */
-int32_t FindEntry(const ZipArchiveHandle handle, const char* entryName,
+int32_t FindEntry(const ZipArchiveHandle handle, const ZipEntryName& entryName,
                   ZipEntry* data);
 
 /*
  * Start iterating over all entries of a zip file. The order of iteration
  * is not guaranteed to be the same as the order of elements
- * in the central directory but is stable for a given zip file. |cookie|
- * must point to a writeable memory location, and will be set to the value
- * of an opaque cookie which can be used to make one or more calls to
- * Next.
+ * in the central directory but is stable for a given zip file. |cookie| will
+ * contain the value of an opaque cookie which can be used to make one or more
+ * calls to Next. All calls to StartIteration must be matched by a call to
+ * EndIteration to free any allocated memory.
  *
  * This method also accepts an optional prefix to restrict iteration to
- * entry names that start with |prefix|.
+ * entry names that start with |optional_prefix|.
  *
  * Returns 0 on success and negative values on failure.
  */
 int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,
-                       const char* prefix);
+                       const ZipEntryName* optional_prefix);
 
 /*
  * Advance to the next element in the zipfile in iteration order.
@@ -152,6 +161,12 @@
 int32_t Next(void* cookie, ZipEntry* data, ZipEntryName *name);
 
 /*
+ * End iteration over all entries of a zip file and frees the memory allocated
+ * in StartIteration.
+ */
+void EndIteration(void* cookie);
+
+/*
  * Uncompress and write an entry to an open file identified by |fd|.
  * |entry->uncompressed_length| bytes will be written to the file at
  * its current offset, and the file will be truncated at the end of
diff --git a/init/bootchart.c b/init/bootchart.c
index f72fcaa..a514261 100644
--- a/init/bootchart.c
+++ b/init/bootchart.c
@@ -119,6 +119,18 @@
     }
 }
 
+static long long
+get_uptime_jiffies()
+{
+    char       buff[64];
+    long long  jiffies = 0;
+
+    if (proc_read("/proc/uptime", buff, sizeof(buff)) > 0)
+        jiffies = 100LL*strtod(buff,NULL);
+
+    return jiffies;
+}
+
 static void
 log_header(void)
 {
@@ -185,22 +197,11 @@
 do_log_uptime(FileBuff  log)
 {
     char  buff[65];
-    int   fd, ret, len;
+    int   len;
 
-    fd = open("/proc/uptime",O_RDONLY);
-    if (fd >= 0) {
-        int  ret;
-        ret = unix_read(fd, buff, 64);
-        close(fd);
-        buff[64] = 0;
-        if (ret >= 0) {
-            long long  jiffies = 100LL*strtod(buff,NULL);
-            int        len;
-            snprintf(buff,sizeof(buff),"%lld\n",jiffies);
-            len = strlen(buff);
-            file_buff_write(log, buff, len);
-        }
-    }
+    snprintf(buff,sizeof(buff),"%lld\n",get_uptime_jiffies());
+    len = strlen(buff);
+    file_buff_write(log, buff, len);
 }
 
 static void
@@ -376,3 +377,9 @@
     file_buff_done(log_procs);
     acct(NULL);
 }
+
+/* called to get time (in ms) used by bootchart */
+long long  bootchart_gettime( void )
+{
+    return 10LL*get_uptime_jiffies();
+}
diff --git a/init/bootchart.h b/init/bootchart.h
index 39d2d4f..ed65e8a 100644
--- a/init/bootchart.h
+++ b/init/bootchart.h
@@ -26,6 +26,7 @@
 extern int   bootchart_init(void);
 extern int   bootchart_step(void);
 extern void  bootchart_finish(void);
+extern long long  bootchart_gettime(void);
 
 # define BOOTCHART_POLLING_MS   200   /* polling period in ms */
 # define BOOTCHART_DEFAULT_TIME_SEC    (2*60)  /* default polling time in seconds */
diff --git a/init/init.c b/init/init.c
index bd1db7a..99474e6 100644
--- a/init/init.c
+++ b/init/init.c
@@ -65,6 +65,7 @@
 
 #if BOOTCHART
 static int   bootchart_count;
+static long long bootchart_time = 0;
 #endif
 
 static char console[32];
@@ -1147,11 +1148,29 @@
 
 #if BOOTCHART
         if (bootchart_count > 0) {
-            if (timeout < 0 || timeout > BOOTCHART_POLLING_MS)
-                timeout = BOOTCHART_POLLING_MS;
-            if (bootchart_step() < 0 || --bootchart_count == 0) {
-                bootchart_finish();
-                bootchart_count = 0;
+            long long current_time;
+            int elapsed_time, remaining_time;
+
+            current_time = bootchart_gettime();
+            elapsed_time = current_time - bootchart_time;
+
+            if (elapsed_time >= BOOTCHART_POLLING_MS) {
+                /* count missed samples */
+                while (elapsed_time >= BOOTCHART_POLLING_MS) {
+                    elapsed_time -= BOOTCHART_POLLING_MS;
+                    bootchart_count--;
+                }
+                /* count may be negative, take a sample anyway */
+                bootchart_time = current_time;
+                if (bootchart_step() < 0 || bootchart_count <= 0) {
+                    bootchart_finish();
+                    bootchart_count = 0;
+                }
+            }
+            if (bootchart_count > 0) {
+                remaining_time = BOOTCHART_POLLING_MS - elapsed_time;
+                if (timeout < 0 || timeout > remaining_time)
+                    timeout = remaining_time;
             }
         }
 #endif
diff --git a/libbacktrace/Android.build.mk b/libbacktrace/Android.build.mk
index 2f55645..2685380 100644
--- a/libbacktrace/Android.build.mk
+++ b/libbacktrace/Android.build.mk
@@ -73,6 +73,7 @@
 ifeq ($(build_type),host)
   # Only build if host builds are supported.
   ifeq ($(build_host),true)
+    LOCAL_CFLAGS += -Wno-extern-c-compat
     ifneq ($($(module)_libc++),)
       include external/libcxx/libcxx.mk
     endif
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index b016a42..12a3bf9 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -124,9 +124,17 @@
 LOCAL_SRC_FILES_arm64 += \
         arch-arm64/android_memset.S \
 
+ifndef ARCH_MIPS_REV6
 LOCAL_SRC_FILES_mips += \
         arch-mips/android_memset.c \
 
+LOCAL_CFLAGS_mips += -DHAVE_MEMSET16 -DHAVE_MEMSET32
+endif
+
+# TODO: switch mips64 back to using arch-mips/android_memset.c
+LOCAL_SRC_FILES_mips64 += \
+#       arch-mips/android_memset.c \
+
 LOCAL_SRC_FILES_x86 += \
         arch-x86/android_memset16.S \
         arch-x86/android_memset32.S \
@@ -137,7 +145,7 @@
 
 LOCAL_CFLAGS_arm += -DHAVE_MEMSET16 -DHAVE_MEMSET32
 LOCAL_CFLAGS_arm64 += -DHAVE_MEMSET16 -DHAVE_MEMSET32
-LOCAL_CFLAGS_mips += -DHAVE_MEMSET16 -DHAVE_MEMSET32
+#LOCAL_CFLAGS_mips64 += -DHAVE_MEMSET16 -DHAVE_MEMSET32
 LOCAL_CFLAGS_x86 += -DHAVE_MEMSET16 -DHAVE_MEMSET32
 LOCAL_CFLAGS_x86_64 += -DHAVE_MEMSET16 -DHAVE_MEMSET32
 
diff --git a/libcutils/open_memstream.c b/libcutils/open_memstream.c
index 5b4388a..1c37321 100644
--- a/libcutils/open_memstream.c
+++ b/libcutils/open_memstream.c
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef HAVE_OPEN_MEMSTREAM
+#if defined(__APPLE__)
 
 /*
  * Implementation of the POSIX open_memstream() function, which Linux has
@@ -378,4 +378,4 @@
 
 #endif
 
-#endif /*!HAVE_OPEN_MEMSTREAM*/
+#endif /* __APPLE__ */
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index 2acc3c3..d3cedd4 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -221,11 +221,9 @@
 
 int get_sched_policy(int tid, SchedPolicy *policy)
 {
-#ifdef HAVE_GETTID
     if (tid == 0) {
         tid = gettid();
     }
-#endif
     pthread_once(&the_once, __initialize);
 
     if (__sys_supports_schedgroups) {
@@ -260,11 +258,9 @@
 
 int set_sched_policy(int tid, SchedPolicy policy)
 {
-#ifdef HAVE_GETTID
     if (tid == 0) {
         tid = gettid();
     }
-#endif
     policy = _policy(policy);
     pthread_once(&the_once, __initialize);
 
diff --git a/libpixelflinger/Android.mk b/libpixelflinger/Android.mk
index 484cf50..6a3a58f 100644
--- a/libpixelflinger/Android.mk
+++ b/libpixelflinger/Android.mk
@@ -44,11 +44,13 @@
 	arch-arm64/col32cb16blend.S \
 	arch-arm64/t32cb16blend.S \
 
+ifndef ARCH_MIPS_REV6
 PIXELFLINGER_SRC_FILES_mips := \
 	codeflinger/MIPSAssembler.cpp \
 	codeflinger/mips_disassem.c \
 	arch-mips/t32cb16blend.S \
 
+endif
 #
 # Shared library
 #
diff --git a/libpixelflinger/scanline.cpp b/libpixelflinger/scanline.cpp
index 26b9a3e..3d14531 100644
--- a/libpixelflinger/scanline.cpp
+++ b/libpixelflinger/scanline.cpp
@@ -39,7 +39,7 @@
 #include "codeflinger/ARMAssembler.h"
 #elif defined(__aarch64__)
 #include "codeflinger/Arm64Assembler.h"
-#elif defined(__mips__) && !defined(__LP64__)
+#elif defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
 #include "codeflinger/MIPSAssembler.h"
 #endif
 //#include "codeflinger/ARMAssemblerOptimizer.h"
@@ -59,7 +59,7 @@
 #   define ANDROID_CODEGEN      ANDROID_CODEGEN_GENERATED
 #endif
 
-#if defined(__arm__) || (defined(__mips__) && !defined(__LP64__)) || defined(__aarch64__)
+#if defined(__arm__) || (defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6) || defined(__aarch64__)
 #   define ANDROID_ARM_CODEGEN  1
 #else
 #   define ANDROID_ARM_CODEGEN  0
@@ -73,7 +73,7 @@
  */
 #define DEBUG_NEEDS  0
 
-#if defined( __mips__) && !defined(__LP64__)
+#if defined( __mips__) && !defined(__LP64__) && __mips_isa_rev < 6
 #define ASSEMBLY_SCRATCH_SIZE   4096
 #elif defined(__aarch64__)
 #define ASSEMBLY_SCRATCH_SIZE   8192
@@ -134,7 +134,7 @@
 #elif defined(__aarch64__)
 extern "C" void scanline_t32cb16blend_arm64(uint16_t*, uint32_t*, size_t);
 extern "C" void scanline_col32cb16blend_arm64(uint16_t *dst, uint32_t col, size_t ct);
-#elif defined(__mips__)  && !defined(__LP64__)
+#elif defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
 extern "C" void scanline_t32cb16blend_mips(uint16_t*, uint32_t*, size_t);
 #endif
 
@@ -286,7 +286,7 @@
 
 #if ANDROID_ARM_CODEGEN
 
-#if defined(__mips__)
+#if defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
 static CodeCache gCodeCache(32 * 1024);
 #elif defined(__aarch64__)
 static CodeCache gCodeCache(48 * 1024);
@@ -2175,7 +2175,7 @@
 
 void scanline_t32cb16blend(context_t* c)
 {
-#if ((ANDROID_CODEGEN >= ANDROID_CODEGEN_ASM) && (defined(__arm__) || (defined(__mips__) && !defined(__LP64__)) || defined(__aarch64__)))
+#if ((ANDROID_CODEGEN >= ANDROID_CODEGEN_ASM) && (defined(__arm__) || (defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6) || defined(__aarch64__)))
     int32_t x = c->iterators.xl;
     size_t ct = c->iterators.xr - x;
     int32_t y = c->iterators.y;
diff --git a/libpixelflinger/tests/codegen/codegen.cpp b/libpixelflinger/tests/codegen/codegen.cpp
index 46c1ccc..148b6f4 100644
--- a/libpixelflinger/tests/codegen/codegen.cpp
+++ b/libpixelflinger/tests/codegen/codegen.cpp
@@ -9,16 +9,18 @@
 #include "codeflinger/CodeCache.h"
 #include "codeflinger/GGLAssembler.h"
 #include "codeflinger/ARMAssembler.h"
+#if defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
 #include "codeflinger/MIPSAssembler.h"
+#endif
 #include "codeflinger/Arm64Assembler.h"
 
-#if defined(__arm__) || defined(__mips__) || defined(__aarch64__)
+#if defined(__arm__) || (defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6) || defined(__aarch64__)
 #   define ANDROID_ARM_CODEGEN  1
 #else
 #   define ANDROID_ARM_CODEGEN  0
 #endif
 
-#if defined (__mips__)
+#if defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
 #define ASSEMBLY_SCRATCH_SIZE   4096
 #elif defined(__aarch64__)
 #define ASSEMBLY_SCRATCH_SIZE   8192
@@ -52,7 +54,7 @@
     GGLAssembler assembler( new ARMAssembler(a) );
 #endif
 
-#if defined(__mips__) && !defined(__LP64__)
+#if defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
     GGLAssembler assembler( new ArmToMipsAssembler(a) );
 #endif
 
diff --git a/libutils/Android.mk b/libutils/Android.mk
index b1dc1f8..856a86c 100644
--- a/libutils/Android.mk
+++ b/libutils/Android.mk
@@ -67,6 +67,9 @@
 ifeq ($(HOST_OS), linux)
 LOCAL_SRC_FILES += Looper.cpp
 endif
+ifeq ($(HOST_OS),darwin)
+LOCAL_CFLAGS += -Wno-unused-parameter
+endif
 LOCAL_MODULE:= libutils
 LOCAL_STATIC_LIBRARIES := liblog
 LOCAL_CFLAGS += $(host_commonCflags)
diff --git a/libutils/Threads.cpp b/libutils/Threads.cpp
index b09d510..03fde97 100644
--- a/libutils/Threads.cpp
+++ b/libutils/Threads.cpp
@@ -306,15 +306,6 @@
     gCreateThreadFn = func;
 }
 
-pid_t androidGetTid()
-{
-#ifdef HAVE_GETTID
-    return gettid();
-#else
-    return getpid();
-#endif
-}
-
 #ifdef HAVE_ANDROID_OS
 int androidSetThreadPriority(pid_t tid, int pri)
 {
diff --git a/libziparchive/Android.mk b/libziparchive/Android.mk
index 705caa5..d96bc63 100644
--- a/libziparchive/Android.mk
+++ b/libziparchive/Android.mk
@@ -63,7 +63,8 @@
 LOCAL_CFLAGS += \
     -DGTEST_OS_LINUX \
     -DGTEST_HAS_STD_STRING \
-    -Werror
+    -Werror \
+    -Wno-unnamed-type-template-args
 LOCAL_SRC_FILES := zip_archive_test.cc
 LOCAL_STATIC_LIBRARIES := libziparchive-host \
 	libz \
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 6ec8f0d..d5d4700 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -385,8 +385,10 @@
   return val;
 }
 
-static uint32_t ComputeHash(const char* str, uint16_t len) {
+static uint32_t ComputeHash(const ZipEntryName& name) {
   uint32_t hash = 0;
+  uint16_t len = name.name_length;
+  const uint8_t* str = name.name;
 
   while (len--) {
     hash = hash * 31 + *str++;
@@ -401,21 +403,21 @@
  */
 static int64_t EntryToIndex(const ZipEntryName* hash_table,
                             const uint32_t hash_table_size,
-                            const char* name, uint16_t length) {
-  const uint32_t hash = ComputeHash(name, length);
+                            const ZipEntryName& name) {
+  const uint32_t hash = ComputeHash(name);
 
   // NOTE: (hash_table_size - 1) is guaranteed to be non-negative.
   uint32_t ent = hash & (hash_table_size - 1);
   while (hash_table[ent].name != NULL) {
-    if (hash_table[ent].name_length == length &&
-        memcmp(hash_table[ent].name, name, length) == 0) {
+    if (hash_table[ent].name_length == name.name_length &&
+        memcmp(hash_table[ent].name, name.name, name.name_length) == 0) {
       return ent;
     }
 
     ent = (ent + 1) & (hash_table_size - 1);
   }
 
-  ALOGV("Zip: Unable to find entry %.*s", length, name);
+  ALOGV("Zip: Unable to find entry %.*s", name.name_length, name.name);
   return kEntryNotFound;
 }
 
@@ -423,8 +425,8 @@
  * Add a new entry to the hash table.
  */
 static int32_t AddToHash(ZipEntryName *hash_table, const uint64_t hash_table_size,
-                         const char* name, uint16_t length) {
-  const uint64_t hash = ComputeHash(name, length);
+                         const ZipEntryName& name) {
+  const uint64_t hash = ComputeHash(name);
   uint32_t ent = hash & (hash_table_size - 1);
 
   /*
@@ -432,17 +434,17 @@
    * Further, we guarantee that the hashtable size is not 0.
    */
   while (hash_table[ent].name != NULL) {
-    if (hash_table[ent].name_length == length &&
-        memcmp(hash_table[ent].name, name, length) == 0) {
+    if (hash_table[ent].name_length == name.name_length &&
+        memcmp(hash_table[ent].name, name.name, name.name_length) == 0) {
       // We've found a duplicate entry. We don't accept it
-      ALOGW("Zip: Found duplicate entry %.*s", length, name);
+      ALOGW("Zip: Found duplicate entry %.*s", name.name_length, name.name);
       return kDuplicateEntry;
     }
     ent = (ent + 1) & (hash_table_size - 1);
   }
 
-  hash_table[ent].name = name;
-  hash_table[ent].name_length = length;
+  hash_table[ent].name = name.name;
+  hash_table[ent].name_length = name.name_length;
   return 0;
 }
 
@@ -638,11 +640,20 @@
     const uint16_t file_name_length = cdr->file_name_length;
     const uint16_t extra_length = cdr->extra_field_length;
     const uint16_t comment_length = cdr->comment_length;
+    const uint8_t* file_name = ptr + sizeof(CentralDirectoryRecord);
+
+    /* check that file name doesn't contain \0 character */
+    if (memchr(file_name, 0, file_name_length) != NULL) {
+      ALOGW("Zip: entry name can't contain \\0 character");
+      goto bail;
+    }
 
     /* add the CDE filename to the hash table */
-    const char* file_name = reinterpret_cast<const char *>(ptr + sizeof(CentralDirectoryRecord));
+    ZipEntryName entry_name;
+    entry_name.name = file_name;
+    entry_name.name_length = file_name_length;
     const int add_result = AddToHash(archive->hash_table,
-        archive->hash_table_size, file_name, file_name_length);
+        archive->hash_table_size, entry_name);
     if (add_result) {
       ALOGW("Zip: Error adding entry to hash table %d", add_result);
       result = add_result;
@@ -751,12 +762,11 @@
 static int32_t FindEntry(const ZipArchive* archive, const int ent,
                          ZipEntry* data) {
   const uint16_t nameLen = archive->hash_table[ent].name_length;
-  const char* name = archive->hash_table[ent].name;
 
   // Recover the start of the central directory entry from the filename
   // pointer.  The filename is the first entry past the fixed-size data,
   // so we can just subtract back from that.
-  const uint8_t* ptr = reinterpret_cast<const uint8_t*>(name);
+  const uint8_t* ptr = archive->hash_table[ent].name;
   ptr -= sizeof(CentralDirectoryRecord);
 
   // This is the base of our mmapped region, we have to sanity check that
@@ -847,7 +857,7 @@
       return kIoError;
     }
 
-    if (memcmp(name, name_buf, nameLen)) {
+    if (memcmp(archive->hash_table[ent].name, name_buf, nameLen)) {
       free(name_buf);
       return kInconsistentInformation;
     }
@@ -884,12 +894,28 @@
 
 struct IterationHandle {
   uint32_t position;
-  const char* prefix;
+  // We're not using vector here because this code is used in the Windows SDK
+  // where the STL is not available.
+  const uint8_t* prefix;
   uint16_t prefix_len;
   ZipArchive* archive;
+
+  IterationHandle() : prefix(NULL), prefix_len(0) {}
+
+  IterationHandle(const ZipEntryName& prefix_name)
+      : prefix_len(prefix_name.name_length) {
+    uint8_t* prefix_copy = new uint8_t[prefix_len];
+    memcpy(prefix_copy, prefix_name.name, prefix_len);
+    prefix = prefix_copy;
+  }
+
+  ~IterationHandle() {
+    delete[] prefix;
+  }
 };
 
-int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr, const char* prefix) {
+int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,
+                       const ZipEntryName* optional_prefix) {
   ZipArchive* archive = (ZipArchive *) handle;
 
   if (archive == NULL || archive->hash_table == NULL) {
@@ -897,32 +923,32 @@
     return kInvalidHandle;
   }
 
-  IterationHandle* cookie = (IterationHandle*) malloc(sizeof(IterationHandle));
+  IterationHandle* cookie =
+      optional_prefix != NULL ? new IterationHandle(*optional_prefix) : new IterationHandle();
   cookie->position = 0;
-  cookie->prefix = prefix;
   cookie->archive = archive;
-  if (prefix != NULL) {
-    cookie->prefix_len = strlen(prefix);
-  }
 
   *cookie_ptr = cookie ;
   return 0;
 }
 
-int32_t FindEntry(const ZipArchiveHandle handle, const char* entryName,
+void EndIteration(void* cookie) {
+  delete reinterpret_cast<IterationHandle*>(cookie);
+}
+
+int32_t FindEntry(const ZipArchiveHandle handle, const ZipEntryName& entryName,
                   ZipEntry* data) {
   const ZipArchive* archive = (ZipArchive*) handle;
-  const int nameLen = strlen(entryName);
-  if (nameLen == 0 || nameLen > 65535) {
-    ALOGW("Zip: Invalid filename %s", entryName);
+  if (entryName.name_length == 0) {
+    ALOGW("Zip: Invalid filename %.*s", entryName.name_length, entryName.name);
     return kInvalidEntryName;
   }
 
   const int64_t ent = EntryToIndex(archive->hash_table,
-    archive->hash_table_size, entryName, nameLen);
+    archive->hash_table_size, entryName);
 
   if (ent < 0) {
-    ALOGV("Zip: Could not find entry %.*s", nameLen, entryName);
+    ALOGV("Zip: Could not find entry %.*s", entryName.name_length, entryName.name);
     return ent;
   }
 
@@ -947,7 +973,7 @@
 
   for (uint32_t i = currentOffset; i < hash_table_length; ++i) {
     if (hash_table[i].name != NULL &&
-        (handle->prefix == NULL ||
+        (handle->prefix_len == 0 ||
          (memcmp(handle->prefix, hash_table[i].name, handle->prefix_len) == 0))) {
       handle->position = (i + 1);
       const int error = FindEntry(archive, i, data);
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index 813a87f..4775de0 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -40,6 +40,27 @@
   '\n'
 };
 
+static const uint16_t kATxtNameLength = 5;
+static const uint16_t kBTxtNameLength = 5;
+static const uint16_t kNonexistentTxtNameLength = 15;
+static const uint16_t kEmptyTxtNameLength = 9;
+
+static const uint8_t kATxtName[kATxtNameLength] = {
+  'a', '.', 't', 'x', 't'
+};
+
+static const uint8_t kBTxtName[kBTxtNameLength] = {
+  'b', '.', 't', 'x', 't'
+};
+
+static const uint8_t kNonexistentTxtName[kNonexistentTxtNameLength] = {
+  'n', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 't', 'x' ,'t'
+};
+
+static const uint8_t kEmptyTxtName[kEmptyTxtNameLength] = {
+  'e', 'm', 'p', 't', 'y', '.', 't', 'x', 't'
+};
+
 static int32_t OpenArchiveWrapper(const std::string& name,
                                   ZipArchiveHandle* handle) {
   const std::string abs_path = test_data_dir + "/" + name;
@@ -108,7 +129,10 @@
   ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
 
   ZipEntry data;
-  ASSERT_EQ(0, FindEntry(handle, "a.txt", &data));
+  ZipEntryName name;
+  name.name = kATxtName;
+  name.name_length = kATxtNameLength;
+  ASSERT_EQ(0, FindEntry(handle, name, &data));
 
   // Known facts about a.txt, from zipinfo -v.
   ASSERT_EQ(63, data.offset);
@@ -118,7 +142,10 @@
   ASSERT_EQ(0x950821c5, data.crc32);
 
   // An entry that doesn't exist. Should be a negative return code.
-  ASSERT_LT(FindEntry(handle, "nonexistent.txt", &data), 0);
+  ZipEntryName absent_name;
+  absent_name.name = kNonexistentTxtName;
+  absent_name.name_length = kNonexistentTxtNameLength;
+  ASSERT_LT(FindEntry(handle, absent_name, &data), 0);
 
   CloseArchive(handle);
 }
@@ -129,7 +156,10 @@
 
   // An entry that's deflated.
   ZipEntry data;
-  ASSERT_EQ(0, FindEntry(handle, "a.txt", &data));
+  ZipEntryName a_name;
+  a_name.name = kATxtName;
+  a_name.name_length = kATxtNameLength;
+  ASSERT_EQ(0, FindEntry(handle, a_name, &data));
   const uint32_t a_size = data.uncompressed_length;
   ASSERT_EQ(a_size, sizeof(kATxtContents));
   uint8_t* buffer = new uint8_t[a_size];
@@ -138,7 +168,10 @@
   delete[] buffer;
 
   // An entry that's stored.
-  ASSERT_EQ(0, FindEntry(handle, "b.txt", &data));
+  ZipEntryName b_name;
+  b_name.name = kBTxtName;
+  b_name.name_length = kBTxtNameLength;
+  ASSERT_EQ(0, FindEntry(handle, b_name, &data));
   const uint32_t b_size = data.uncompressed_length;
   ASSERT_EQ(b_size, sizeof(kBTxtContents));
   buffer = new uint8_t[b_size];
@@ -184,7 +217,10 @@
   ASSERT_EQ(0, OpenArchiveFd(fd, "EmptyEntriesTest", &handle));
 
   ZipEntry entry;
-  ASSERT_EQ(0, FindEntry(handle, "empty.txt", &entry));
+  ZipEntryName empty_name;
+  empty_name.name = kEmptyTxtName;
+  empty_name.name_length = kEmptyTxtNameLength;
+  ASSERT_EQ(0, FindEntry(handle, empty_name, &entry));
   ASSERT_EQ(static_cast<uint32_t>(0), entry.uncompressed_length);
   uint8_t buffer[1];
   ASSERT_EQ(0, ExtractToMemory(handle, &entry, buffer, 1));
@@ -231,7 +267,10 @@
   ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
 
   ZipEntry entry;
-  ASSERT_EQ(0, FindEntry(handle, "a.txt", &entry));
+  ZipEntryName name;
+  name.name = kATxtName;
+  name.name_length = kATxtNameLength;
+  ASSERT_EQ(0, FindEntry(handle, name, &entry));
   ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, fd));
 
 
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
index c6dc174..ea4e8c8 100644
--- a/logd/LogTimes.cpp
+++ b/logd/LogTimes.cpp
@@ -119,8 +119,7 @@
     SocketClient *client = me->mClient;
     if (!client) {
         me->error();
-        pthread_exit(NULL);
-        // NOTREACH
+        return NULL;
     }
 
     LogBuffer &logbuf = me->mReader.logbuf();
@@ -154,9 +153,6 @@
 
     unlock();
 
-    pthread_exit(NULL);
-
-    // NOTREACH
     pthread_cleanup_pop(true);
 
     return NULL;