Merge changes from topics "fdsan_ziparchive_type", "fdsan_java_socket"

* changes:
  fdsan: improve documentation.
  fdsan: add type for libziparchive's ZipArchive.
  fdsan: add types for Java sockets.
diff --git a/benchmarks/README.md b/benchmarks/README.md
index b3f0c3d..2616a51 100644
--- a/benchmarks/README.md
+++ b/benchmarks/README.md
@@ -13,8 +13,8 @@
     $ mma
     $ adb remount
     $ adb sync
-    $ adb shell /data/nativetest/bionic-benchmarks/bionic-benchmarks
-    $ adb shell /data/nativetest64/bionic-benchmarks/bionic-benchmarks
+    $ adb shell /data/benchmarktest/bionic-benchmarks/bionic-benchmarks
+    $ adb shell /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks
 
 When operated without specifying an xml file, the default is to run all
 of the benchmarks in alphabetical order.
diff --git a/benchmarks/tests/interface_test.cpp b/benchmarks/tests/interface_test.cpp
index 89b6011..8e0e4f2 100644
--- a/benchmarks/tests/interface_test.cpp
+++ b/benchmarks/tests/interface_test.cpp
@@ -540,6 +540,15 @@
     "BM_string_strlen/32768/0/iterations:1\n"
     "BM_string_strlen/65536/0/iterations:1\n"
     "BM_string_strlen/131072/0/iterations:1\n"
+    "BM_string_strncmp/8/0/0/iterations:1\n"
+    "BM_string_strncmp/64/0/0/iterations:1\n"
+    "BM_string_strncmp/512/0/0/iterations:1\n"
+    "BM_string_strncmp/1024/0/0/iterations:1\n"
+    "BM_string_strncmp/8192/0/0/iterations:1\n"
+    "BM_string_strncmp/16384/0/0/iterations:1\n"
+    "BM_string_strncmp/32768/0/0/iterations:1\n"
+    "BM_string_strncmp/65536/0/0/iterations:1\n"
+    "BM_string_strncmp/131072/0/0/iterations:1\n"
     "BM_string_strstr/8/0/0/iterations:1\n"
     "BM_string_strstr/64/0/0/iterations:1\n"
     "BM_string_strstr/512/0/0/iterations:1\n"
diff --git a/docs/status.md b/docs/status.md
index c8c06c6..b6439a0 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -27,7 +27,7 @@
 Missing functionality:
   * `<aio.h>`
   * `<wordexp.h>`
-  * Thread cancellation
+  * Thread cancellation (`pthread_cancel`).
   * Robust mutexes
 
 Run `./libc/tools/check-symbols-glibc.py` in bionic/ for the current
diff --git a/libc/Android.bp b/libc/Android.bp
index d7ad117..57173d1 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -189,7 +189,6 @@
 
         "upstream-netbsd/lib/libc/isc/ev_streams.c",
         "upstream-netbsd/lib/libc/isc/ev_timers.c",
-        "upstream-netbsd/lib/libc/resolv/mtctxres.c",
     ],
 
     cflags: [
diff --git a/libc/SECCOMP_WHITELIST_APP.TXT b/libc/SECCOMP_WHITELIST_APP.TXT
index faa2d63..9aa4260 100644
--- a/libc/SECCOMP_WHITELIST_APP.TXT
+++ b/libc/SECCOMP_WHITELIST_APP.TXT
@@ -25,17 +25,10 @@
 #
 # This file is processed by a python script named genseccomp.py.
 
-# Needed for debugging 32-bit Chrome
-int	pipe:pipe(int pipefd[2])	arm,x86,mips
-
 # b/34651972
 int	access:access(const char *pathname, int mode)	arm,x86,mips
 int	stat64:stat64(const char*, struct stat64*)	arm,x86,mips
 
-# b/34813887
-int	open:open(const char *path, int oflag, ... ) arm,x86,x86_64,mips
-int	getdents:getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count) arm,x86,x86_64,mips
-
 # b/34719286
 int	eventfd:eventfd(unsigned int initval, int flags)	arm,x86,mips
 
diff --git a/libc/SECCOMP_WHITELIST_COMMON.TXT b/libc/SECCOMP_WHITELIST_COMMON.TXT
index f6e9539..2faa559 100644
--- a/libc/SECCOMP_WHITELIST_COMMON.TXT
+++ b/libc/SECCOMP_WHITELIST_COMMON.TXT
@@ -51,6 +51,13 @@
 # b/34763393
 int	seccomp:seccomp(unsigned int operation, unsigned int flags, void *args)	all
 
+# Needed for debugging 32-bit Chrome
+int	pipe:pipe(int pipefd[2])	arm,x86,mips
+
+# b/34813887
+int	open:open(const char *path, int oflag, ... ) arm,x86,x86_64,mips
+int	getdents:getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count) arm,x86,x86_64,mips
+
 # syscalls needed to boot android
 int	sigreturn:sigreturn(unsigned long __unused)	arm,x86,mips
 
diff --git a/libc/bionic/NetdClient.cpp b/libc/bionic/NetdClient.cpp
index 966cbcc..a5c519e 100644
--- a/libc/bionic/NetdClient.cpp
+++ b/libc/bionic/NetdClient.cpp
@@ -39,7 +39,7 @@
 static void netdClientInitImpl() {
     // Prevent netd from looping back fwmarkd connections to itself. It would work, but it's
     // a deadlock hazard and unnecessary overhead for the resolver.
-    if (getuid() == 0 && strcmp(getprogname(), "netd") == 0) {
+    if (getuid() == 0 && strcmp(basename(getprogname()), "netd") == 0) {
         async_safe_format_log(ANDROID_LOG_INFO, "netdClient",
                               "Skipping libnetd_client init since *we* are netd");
         return;
diff --git a/libc/upstream-netbsd/android/include/resolv_mt.h b/libc/upstream-netbsd/android/include/resolv_mt.h
new file mode 100644
index 0000000..664ae93
--- /dev/null
+++ b/libc/upstream-netbsd/android/include/resolv_mt.h
@@ -0,0 +1,4 @@
+#pragma once
+
+// Android never enabled the per-thread code, so this was always static like glibc.
+static char inet_nsap_ntoa_tmpbuf[255*3];
diff --git a/libc/upstream-netbsd/lib/libc/include/resolv_mt.h b/libc/upstream-netbsd/lib/libc/include/resolv_mt.h
deleted file mode 100644
index 73a8dcc..0000000
--- a/libc/upstream-netbsd/lib/libc/include/resolv_mt.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*	$NetBSD: resolv_mt.h,v 1.1.1.3 2009/04/12 16:35:44 christos Exp $	*/
-
-#ifndef _RESOLV_MT_H
-#define _RESOLV_MT_H
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-
-/* Access functions for the libresolv private interface */
-
-int	__res_enable_mt(void);
-int	__res_disable_mt(void);
-
-/* Per-thread context */
-
-typedef struct {
-int	no_hosts_fallback_private;
-int	retry_save;
-int	retry_private;
-char	inet_nsap_ntoa_tmpbuf[255*3];
-char	sym_ntos_unname[20];
-char	sym_ntop_unname[20];
-char	p_option_nbuf[40];
-char	p_time_nbuf[40];
-char	precsize_ntoa_retbuf[sizeof "90000000.00"];
-char	loc_ntoa_tmpbuf[sizeof
-"1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"];
-char	p_secstodate_output[15];
-} mtctxres_t;
-
-/* Thread-specific data (TSD) */
-
-mtctxres_t	*___mtctxres(void);
-#define mtctxres	(___mtctxres())
-
-/* Various static data that should be TSD */
-
-#define sym_ntos_unname		(mtctxres->sym_ntos_unname)
-#define sym_ntop_unname		(mtctxres->sym_ntop_unname)
-#define inet_nsap_ntoa_tmpbuf	(mtctxres->inet_nsap_ntoa_tmpbuf)
-#define p_option_nbuf		(mtctxres->p_option_nbuf)
-#define p_time_nbuf		(mtctxres->p_time_nbuf)
-#define precsize_ntoa_retbuf	(mtctxres->precsize_ntoa_retbuf)
-#define loc_ntoa_tmpbuf		(mtctxres->loc_ntoa_tmpbuf)
-#define p_secstodate_output	(mtctxres->p_secstodate_output)
-
-#endif /* _RESOLV_MT_H */
diff --git a/libc/upstream-netbsd/lib/libc/resolv/mtctxres.c b/libc/upstream-netbsd/lib/libc/resolv/mtctxres.c
deleted file mode 100644
index 6e3281a..0000000
--- a/libc/upstream-netbsd/lib/libc/resolv/mtctxres.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/*	$NetBSD: mtctxres.c,v 1.4 2007/03/30 20:40:52 ghen Exp $	*/
-
-#include <port_before.h>
-#ifdef DO_PTHREADS
-#include <pthread.h>
-#endif
-#include <errno.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <string.h>
-#include <resolv_mt.h>
-#include <port_after.h>
-
-#ifdef DO_PTHREADS
-static pthread_key_t	key;
-static int		mt_key_initialized = 0;
-
-static int		__res_init_ctx(void);
-static void		__res_destroy_ctx(void *);
-
-#if defined(sun) && !defined(__GNUC__)
-#pragma init	(_mtctxres_init)
-#endif
-#endif
-
-static mtctxres_t	sharedctx;
-
-#ifdef DO_PTHREADS
-/*
- * Initialize the TSD key. By doing this at library load time, we're
- * implicitly running without interference from other threads, so there's
- * no need for locking.
- */
-static void
-_mtctxres_init(void) {
-	int pthread_keycreate_ret;
-
-	pthread_keycreate_ret = pthread_key_create(&key, __res_destroy_ctx);
-	if (pthread_keycreate_ret == 0)
-		mt_key_initialized = 1;
-}
-#endif
-
-/*
- * To support binaries that used the private MT-safe interface in
- * Solaris 8, we still need to provide the __res_enable_mt()
- * and __res_disable_mt() entry points. They're do-nothing routines.
- */
-int
-__res_enable_mt(void) {
-	return (-1);
-}
-
-int
-__res_disable_mt(void) {
-	return (0);
-}
-
-#ifdef DO_PTHREADS
-static int
-__res_init_ctx(void) {
-
-	mtctxres_t	*mt;
-	int		ret;
-
-
-	if (pthread_getspecific(key) != 0) {
-		/* Already exists */
-		return (0);
-	}
-
-	if ((mt = malloc(sizeof (mtctxres_t))) == 0) {
-		errno = ENOMEM;
-		return (-1);
-	}
-
-	memset(mt, 0, sizeof (mtctxres_t));
-
-	if ((ret = pthread_setspecific(key, mt)) != 0) {
-		free(mt);
-		errno = ret;
-		return (-1);
-	}
-
-	return (0);
-}
-
-static void
-__res_destroy_ctx(void *value) {
-
-	mtctxres_t	*mt = (mtctxres_t *)value;
-
-	if (mt != 0)
-		free(mt);
-}
-#endif
-
-mtctxres_t *
-___mtctxres(void) {
-#ifdef DO_PTHREADS
-	mtctxres_t	*mt;
-
-	/*
-	 * This if clause should only be executed if we are linking
-	 * statically.  When linked dynamically _mtctxres_init() should
-	 * be called at binding time due the #pragma above.
-	 */
-	if (!mt_key_initialized) {
-		static pthread_mutex_t keylock = PTHREAD_MUTEX_INITIALIZER;
-                if (pthread_mutex_lock(&keylock) == 0) {
-			_mtctxres_init();
-			(void) pthread_mutex_unlock(&keylock);
-		}
-	}
-
-	/*
-	 * If we have already been called in this thread return the existing
-	 * context.  Otherwise recreat a new context and return it.  If
-	 * that fails return a global context.
-	 */
-	if (mt_key_initialized) {
-		if (((mt = pthread_getspecific(key)) != 0) ||
-		    (__res_init_ctx() == 0 &&
-		     (mt = pthread_getspecific(key)) != 0)) {
-			return (mt);
-		}
-	}
-#endif
-	return (&sharedctx);
-}
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 0a7ccd8..8bf4c94 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -257,8 +257,10 @@
   }
 
   if (header_.e_machine != GetTargetElfMachine()) {
-    DL_ERR("\"%s\" has unexpected e_machine: %d (%s)", name_.c_str(), header_.e_machine,
-           EM_to_string(header_.e_machine));
+    DL_ERR("\"%s\" is for %s (%d) instead of %s (%d)",
+           name_.c_str(),
+           EM_to_string(header_.e_machine), header_.e_machine,
+           EM_to_string(GetTargetElfMachine()), GetTargetElfMachine());
     return false;
   }
 
diff --git a/tests/membarrier_test.cpp b/tests/membarrier_test.cpp
index 4c58d30..9e871c7 100644
--- a/tests/membarrier_test.cpp
+++ b/tests/membarrier_test.cpp
@@ -28,10 +28,10 @@
   ~ScopedErrnoCleaner() { errno = 0; }
 };
 
-bool HasMembarrier() {
+bool HasMembarrier(int membarrier_cmd) {
   ScopedErrnoCleaner errno_cleaner;
-  bool present = syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0) > 0;
-  return present;
+  int supported_cmds = syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
+  return (supported_cmds > 0) && ((supported_cmds & membarrier_cmd) != 0);
 }
 
 TEST(membarrier, query) {
@@ -45,22 +45,46 @@
 }
 
 TEST(membarrier, global_barrier) {
-  if (!HasMembarrier()) {
+  if (!HasMembarrier(MEMBARRIER_CMD_GLOBAL)) {
+    GTEST_LOG_(INFO) << "MEMBARRIER_CMD_GLOBAL not supported, skipping test.";
     return;
   }
+  ASSERT_EQ(0, syscall(__NR_membarrier, MEMBARRIER_CMD_GLOBAL, 0));
+}
 
-  ScopedErrnoCleaner errno_cleaner;
-  int supported = syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
-  ASSERT_LE(0, supported);
-
-  if ((supported & MEMBARRIER_CMD_GLOBAL) != 0) {
-    ASSERT_EQ(0, syscall(__NR_membarrier, MEMBARRIER_CMD_GLOBAL, 0));
+static const char* MembarrierCommandToName(int membarrier_cmd) {
+  switch (membarrier_cmd) {
+  case MEMBARRIER_CMD_QUERY:
+    return "MEMBARRIER_CMD_QUERY";
+  case MEMBARRIER_CMD_GLOBAL:
+    return "MEMBARRIER_CMD_GLOBAL";
+  case MEMBARRIER_CMD_GLOBAL_EXPEDITED:
+    return "MEMBARRIER_CMD_GLOBAL_EXPEDITED";
+  case MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED:
+    return "MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED";
+  case MEMBARRIER_CMD_PRIVATE_EXPEDITED:
+    return "MEMBARRIER_CMD_PRIVATE_EXPEDITED";
+  case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED:
+    return "MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED";
+  case MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE:
+    return "MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE";
+  case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE:
+    return "MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE";
+  default:
+    return "MEMBARRIER_UNKNOWN";
   }
 }
 
 static void TestRegisterAndBarrierCommands(int membarrier_cmd_register,
                                            int membarrier_cmd_barrier) {
-  if (!HasMembarrier()) {
+  if (!HasMembarrier(membarrier_cmd_register)) {
+    GTEST_LOG_(INFO) << MembarrierCommandToName(membarrier_cmd_register)
+        << " not supported, skipping test.";
+    return;
+  }
+  if (!HasMembarrier(membarrier_cmd_barrier)) {
+    GTEST_LOG_(INFO) << MembarrierCommandToName(membarrier_cmd_barrier)
+        << " not supported, skipping test.";
     return;
   }