Merge "Revert "Move seccomp policy to bionic""
diff --git a/libc/bionic/__cxa_guard.cpp b/libc/bionic/__cxa_guard.cpp
index 97284d5..06926df 100644
--- a/libc/bionic/__cxa_guard.cpp
+++ b/libc/bionic/__cxa_guard.cpp
@@ -79,38 +79,33 @@
 #define CONSTRUCTION_UNDERWAY_WITH_WAITER       0x200
 
 extern "C" int __cxa_guard_acquire(_guard_t* gv) {
-  int old_value = atomic_load_explicit(&gv->state, memory_order_relaxed);
+  int old_value = atomic_load_explicit(&gv->state, memory_order_acquire);
+  // In the common CONSTRUCTION_COMPLETE case we have to ensure that all the stores performed by
+  // the construction function are observable on this CPU after we exit. A similar constraint may
+  // apply in the CONSTRUCTION_NOT_YET_STARTED case with a prior abort.
 
   while (true) {
     if (old_value == CONSTRUCTION_COMPLETE) {
-      // A load_acquire operation is need before exiting with COMPLETE state, as we have to ensure
-      // that all the stores performed by the construction function are observable on this CPU
-      // after we exit.
-      atomic_thread_fence(memory_order_acquire);
       return 0;
     } else if (old_value == CONSTRUCTION_NOT_YET_STARTED) {
       if (!atomic_compare_exchange_weak_explicit(&gv->state, &old_value,
                                                   CONSTRUCTION_UNDERWAY_WITHOUT_WAITER,
-                                                  memory_order_relaxed,
-                                                  memory_order_relaxed)) {
+                                                  memory_order_acquire /* or relaxed in C++17 */,
+                                                  memory_order_acquire)) {
         continue;
       }
-      // The acquire fence may not be needed. But as described in section 3.3.2 of
-      // the Itanium C++ ABI specification, it probably has to behave like the
-      // acquisition of a mutex, which needs an acquire fence.
-      atomic_thread_fence(memory_order_acquire);
       return 1;
     } else if (old_value == CONSTRUCTION_UNDERWAY_WITHOUT_WAITER) {
       if (!atomic_compare_exchange_weak_explicit(&gv->state, &old_value,
                                                  CONSTRUCTION_UNDERWAY_WITH_WAITER,
-                                                 memory_order_relaxed,
-                                                 memory_order_relaxed)) {
+                                                 memory_order_acquire /* or relaxed in C++17 */,
+                                                 memory_order_acquire)) {
         continue;
       }
     }
 
     __futex_wait_ex(&gv->state, false, CONSTRUCTION_UNDERWAY_WITH_WAITER, false, nullptr);
-    old_value = atomic_load_explicit(&gv->state, memory_order_relaxed);
+    old_value = atomic_load_explicit(&gv->state, memory_order_acquire);
   }
 }
 
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
index 0f2a7b5..ec1d18f 100644
--- a/libc/bionic/system_properties.cpp
+++ b/libc/bionic/system_properties.cpp
@@ -34,7 +34,6 @@
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -47,6 +46,7 @@
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/uio.h>
 #include <sys/un.h>
 #include <sys/xattr.h>
 
@@ -487,8 +487,8 @@
 class PropertyServiceConnection {
  public:
   PropertyServiceConnection() : last_error_(0) {
-    fd_ = socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
-    if (fd_ == -1) {
+    socket_ = ::socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
+    if (socket_ == -1) {
       last_error_ = errno;
       return;
     }
@@ -500,54 +500,33 @@
     addr.sun_family = AF_LOCAL;
     socklen_t alen = namelen + offsetof(sockaddr_un, sun_path) + 1;
 
-    if (TEMP_FAILURE_RETRY(connect(fd_, reinterpret_cast<sockaddr*>(&addr), alen)) == -1) {
-      close(fd_);
-      fd_ = -1;
+    if (TEMP_FAILURE_RETRY(connect(socket_, reinterpret_cast<sockaddr*>(&addr), alen)) == -1) {
+      close(socket_);
+      socket_ = -1;
       last_error_ = errno;
     }
   }
 
   bool IsValid() {
-    return fd_ != -1;
+    return socket_ != -1;
   }
 
   int GetLastError() {
     return last_error_;
   }
 
-  bool SendUint32(uint32_t value) {
-    int result = TEMP_FAILURE_RETRY(send(fd_, &value, sizeof(value), 0));
-    return CheckSendRecvResult(result, sizeof(value));
-  }
-
-  bool SendString(const char* value) {
-    uint32_t valuelen = strlen(value);
-    if (!SendUint32(valuelen)) {
-      return false;
-    }
-
-    // Trying to send even 0 bytes to closed socket may lead to
-    // broken pipe (http://b/34670529).
-    if (valuelen == 0) {
-      return true;
-    }
-
-    int result = TEMP_FAILURE_RETRY(send(fd_, value, valuelen, 0));
-    return CheckSendRecvResult(result, valuelen);
-  }
-
   bool RecvInt32(int32_t* value) {
-    int result = TEMP_FAILURE_RETRY(recv(fd_, value, sizeof(*value), MSG_WAITALL));
+    int result = TEMP_FAILURE_RETRY(recv(socket_, value, sizeof(*value), MSG_WAITALL));
     return CheckSendRecvResult(result, sizeof(*value));
   }
 
-  int GetFd() {
-    return fd_;
+  int socket() {
+    return socket_;
   }
 
   ~PropertyServiceConnection() {
-    if (fd_ != -1) {
-      close(fd_);
+    if (socket_ != -1) {
+      close(socket_);
     }
   }
 
@@ -564,8 +543,69 @@
     return last_error_ == 0;
   }
 
-  int fd_;
+  int socket_;
   int last_error_;
+
+  friend class SocketWriter;
+};
+
+class SocketWriter {
+ public:
+  explicit SocketWriter(PropertyServiceConnection* connection)
+      : connection_(connection), iov_index_(0), uint_buf_index_(0)
+  {}
+
+  SocketWriter& WriteUint32(uint32_t value) {
+    CHECK(uint_buf_index_ < kUintBufSize);
+    CHECK(iov_index_ < kIovSize);
+    uint32_t* ptr = uint_buf_ + uint_buf_index_;
+    uint_buf_[uint_buf_index_++] = value;
+    iov_[iov_index_].iov_base = ptr;
+    iov_[iov_index_].iov_len = sizeof(*ptr);
+    ++iov_index_;
+    return *this;
+  }
+
+  SocketWriter& WriteString(const char* value) {
+    uint32_t valuelen = strlen(value);
+    WriteUint32(valuelen);
+    if (valuelen == 0) {
+      return *this;
+    }
+
+    CHECK(iov_index_ < kIovSize);
+    iov_[iov_index_].iov_base = const_cast<char*>(value);
+    iov_[iov_index_].iov_len = valuelen;
+    ++iov_index_;
+
+    return *this;
+  }
+
+  bool Send() {
+    if (!connection_->IsValid()) {
+      return false;
+    }
+
+    if (writev(connection_->socket(), iov_, iov_index_) == -1) {
+      connection_->last_error_ = errno;
+      return false;
+    }
+
+    iov_index_ = uint_buf_index_ = 0;
+    return true;
+  }
+
+ private:
+  static constexpr size_t kUintBufSize = 8;
+  static constexpr size_t kIovSize = 8;
+
+  PropertyServiceConnection* connection_;
+  iovec iov_[kIovSize];
+  size_t iov_index_;
+  uint32_t uint_buf_[kUintBufSize];
+  size_t uint_buf_index_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(SocketWriter);
 };
 
 struct prop_msg {
@@ -581,9 +621,9 @@
   }
 
   int result = -1;
-  int fd = connection.GetFd();
+  int s = connection.socket();
 
-  const int num_bytes = TEMP_FAILURE_RETRY(send(fd, msg, sizeof(prop_msg), 0));
+  const int num_bytes = TEMP_FAILURE_RETRY(send(s, msg, sizeof(prop_msg), 0));
   if (num_bytes == sizeof(prop_msg)) {
     // We successfully wrote to the property server but now we
     // wait for the property server to finish its work.  It
@@ -593,7 +633,7 @@
     // once the socket closes.  Out of paranoia we cap our poll
     // at 250 ms.
     pollfd pollfds[1];
-    pollfds[0].fd = fd;
+    pollfds[0].fd = s;
     pollfds[0].events = 0;
     const int poll_result = TEMP_FAILURE_RETRY(poll(pollfds, 1, 250 /* ms */));
     if (poll_result == 1 && (pollfds[0].revents & POLLHUP) != 0) {
@@ -1230,7 +1270,6 @@
     detect_protocol_version();
   }
 
-  int result = -1;
   if (g_propservice_protocol_version == kProtocolVersion1) {
     // Old protocol does not support long names
     if (strlen(key) >= PROP_NAME_MAX) return -1;
@@ -1241,27 +1280,60 @@
     strlcpy(msg.name, key, sizeof msg.name);
     strlcpy(msg.value, value, sizeof msg.value);
 
-    result = send_prop_msg(&msg);
+    return send_prop_msg(&msg);
   } else {
     // Use proper protocol
     PropertyServiceConnection connection;
-    if (connection.IsValid() && connection.SendUint32(PROP_MSG_SETPROP2) &&
-        connection.SendString(key) && connection.SendString(value) &&
-        connection.RecvInt32(&result)) {
-      if (result != PROP_SUCCESS) {
-        __libc_format_log(ANDROID_LOG_WARN, "libc",
-                          "Unable to set property \"%s\" to \"%s\": error code: 0x%x", key, value,
-                          result);
-      }
-    } else {
-      result = connection.GetLastError();
-      __libc_format_log(ANDROID_LOG_WARN, "libc",
-                        "Unable to set property \"%s\" to \"%s\": error code: 0x%x (%s)", key,
-                        value, result, strerror(result));
+    if (!connection.IsValid()) {
+      errno = connection.GetLastError();
+      __libc_format_log(ANDROID_LOG_WARN,
+                        "libc",
+                        "Unable to set property \"%s\" to \"%s\": connection failed; errno=%d (%s)",
+                        key,
+                        value,
+                        errno,
+                        strerror(errno));
+      return -1;
     }
-  }
 
-  return result != 0 ? -1 : 0;
+    SocketWriter writer(&connection);
+    if (!writer.WriteUint32(PROP_MSG_SETPROP2).WriteString(key).WriteString(value).Send()) {
+      errno = connection.GetLastError();
+      __libc_format_log(ANDROID_LOG_WARN,
+                        "libc",
+                        "Unable to set property \"%s\" to \"%s\": write failed; errno=%d (%s)",
+                        key,
+                        value,
+                        errno,
+                        strerror(errno));
+      return -1;
+    }
+
+    int result = -1;
+    if (!connection.RecvInt32(&result)) {
+      errno = connection.GetLastError();
+      __libc_format_log(ANDROID_LOG_WARN,
+                        "libc",
+                        "Unable to set property \"%s\" to \"%s\": recv failed; errno=%d (%s)",
+                        key,
+                        value,
+                        errno,
+                        strerror(errno));
+      return -1;
+    }
+
+    if (result != PROP_SUCCESS) {
+      __libc_format_log(ANDROID_LOG_WARN,
+                        "libc",
+                        "Unable to set property \"%s\" to \"%s\": error code: 0x%x",
+                        key,
+                        value,
+                        result);
+      return -1;
+    }
+
+    return 0;
+  }
 }
 
 int __system_property_update(prop_info* pi, const char* value, unsigned int len) {
diff --git a/libc/include/sys/_system_properties.h b/libc/include/sys/_system_properties.h
index 186d390..f8dbd33 100644
--- a/libc/include/sys/_system_properties.h
+++ b/libc/include/sys/_system_properties.h
@@ -30,7 +30,6 @@
 #define _INCLUDE_SYS__SYSTEM_PROPERTIES_H
 
 #include <sys/cdefs.h>
-#include <stdbool.h>
 #include <stdint.h>
 
 #ifndef _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
@@ -122,25 +121,6 @@
 */
 uint32_t __system_property_serial(const prop_info* pi);
 
-/*
- * Waits for the specific system property identified by `pi` to be updated
- * past `old_serial`. Waits no longer than `relative_timeout`, or forever
- * if `relaive_timeout` is null.
- *
- * If `pi` is null, waits for the global serial number instead.
- *
- * If you don't know the current serial, use 0.
- *
- * Returns true and updates `*new_serial_ptr` on success, or false if the call
- * timed out.
- */
-struct timespec;
-bool __system_property_wait(const prop_info* pi,
-                            uint32_t old_serial,
-                            uint32_t* new_serial_ptr,
-                            const struct timespec* relative_timeout)
-    __INTRODUCED_IN_FUTURE;
-
 /* Initialize the system properties area in read only mode.
  * Should be done by all processes that need to read system
  * properties.
diff --git a/libc/include/sys/epoll.h b/libc/include/sys/epoll.h
index 4ec8969..b7fdd4d 100644
--- a/libc/include/sys/epoll.h
+++ b/libc/include/sys/epoll.h
@@ -31,11 +31,17 @@
 
 #include <sys/cdefs.h>
 #include <sys/types.h>
-#include <fcntl.h> /* For O_CLOEXEC. */
 #include <signal.h> /* For sigset_t. */
 
+#include <linux/eventpoll.h>
+/* TODO: https://lkml.org/lkml/2017/2/23/416 has a better fix. */
+#undef EPOLLWAKEUP
+#undef EPOLLONESHOT
+#undef EPOLLET
+
 __BEGIN_DECLS
 
+/* TODO: remove once https://lkml.org/lkml/2017/2/23/417 is upstream. */
 #define EPOLLIN          0x00000001
 #define EPOLLPRI         0x00000002
 #define EPOLLOUT         0x00000004
@@ -51,12 +57,6 @@
 #define EPOLLONESHOT     0x40000000
 #define EPOLLET          0x80000000
 
-#define EPOLL_CTL_ADD    1
-#define EPOLL_CTL_DEL    2
-#define EPOLL_CTL_MOD    3
-
-#define EPOLL_CLOEXEC O_CLOEXEC
-
 typedef union epoll_data {
   void* ptr;
   int fd;
diff --git a/libc/include/sys/system_properties.h b/libc/include/sys/system_properties.h
index fb90251..b55566e 100644
--- a/libc/include/sys/system_properties.h
+++ b/libc/include/sys/system_properties.h
@@ -30,6 +30,7 @@
 #define _INCLUDE_SYS_SYSTEM_PROPERTIES_H
 
 #include <sys/cdefs.h>
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
 
@@ -68,6 +69,25 @@
 int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie)
   __INTRODUCED_IN(19);
 
+/*
+ * Waits for the specific system property identified by `pi` to be updated
+ * past `old_serial`. Waits no longer than `relative_timeout`, or forever
+ * if `relaive_timeout` is null.
+ *
+ * If `pi` is null, waits for the global serial number instead.
+ *
+ * If you don't know the current serial, use 0.
+ *
+ * Returns true and updates `*new_serial_ptr` on success, or false if the call
+ * timed out.
+ */
+struct timespec;
+bool __system_property_wait(const prop_info* pi,
+                            uint32_t old_serial,
+                            uint32_t* new_serial_ptr,
+                            const struct timespec* relative_timeout)
+    __INTRODUCED_IN_FUTURE;
+
 /* Deprecated. In Android O and above, there's no limit on property name length. */
 #define PROP_NAME_MAX   32
 /* Deprecated. Use __system_property_read_callback instead. */
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index d5577da..620bb31 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -75,6 +75,8 @@
     "SIGRTMAX": "__SIGRTMAX",
     # We want to support both BSD and Linux member names in struct udphdr.
     "udphdr": "__kernel_udphdr",
+    # The kernel's struct epoll_event just has __u64 for the data.
+    "epoll_event": "__kernel_uapi_epoll_event",
     }
 
 # this is the set of known static inline functions that we want to keep
diff --git a/libc/kernel/uapi/linux/eventpoll.h b/libc/kernel/uapi/linux/eventpoll.h
index ec51b9f..6c7e355 100644
--- a/libc/kernel/uapi/linux/eventpoll.h
+++ b/libc/kernel/uapi/linux/eventpoll.h
@@ -37,7 +37,7 @@
 #define EPOLL_PACKED
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #endif
-struct epoll_event {
+struct __kernel_uapi_epoll_event {
   __u32 events;
   __u64 data;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index ebe249f..9ad26ff 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -185,9 +185,6 @@
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
-    __system_properties_init;
-    __system_property_area__; # var
-    __system_property_area_init; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_area_serial; # introduced=23
     __system_property_find;
     __system_property_foreach; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
@@ -195,8 +192,6 @@
     __system_property_read;
     __system_property_serial; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_set; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
-    __system_property_set_filename; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
-    __system_property_wait_any; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __timer_create; # arm x86 mips
     __timer_delete; # arm x86 mips
     __timer_getoverrun; # arm x86 mips
@@ -1538,11 +1533,16 @@
 LIBC_DEPRECATED {
   global:
     __system_property_find_nth;
+    __system_property_wait_any;
 };
 
 LIBC_PLATFORM {
   global:
+    __system_properties_init;
+    __system_property_area__; # var
     __system_property_add;
+    __system_property_area_init;
+    __system_property_set_filename;
     __system_property_update;
     android_net_res_stats_get_info_for_net;
     android_net_res_stats_aggregate;
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index 74d0171..4953380 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -130,9 +130,6 @@
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
-    __system_properties_init;
-    __system_property_area__; # var
-    __system_property_area_init; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_area_serial; # introduced=23
     __system_property_find;
     __system_property_foreach; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
@@ -140,8 +137,6 @@
     __system_property_read;
     __system_property_serial; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_set; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
-    __system_property_set_filename; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
-    __system_property_wait_any; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __umask_chk; # introduced-arm=18 introduced-arm64=21 introduced-mips=18 introduced-mips64=21 introduced-x86=18 introduced-x86_64=21
     __vsnprintf_chk; # introduced-arm=17 introduced-arm64=21 introduced-mips=17 introduced-mips64=21 introduced-x86=17 introduced-x86_64=21
     __vsprintf_chk; # introduced-arm=17 introduced-arm64=21 introduced-mips=17 introduced-mips64=21 introduced-x86=17 introduced-x86_64=21
@@ -1255,11 +1250,16 @@
 LIBC_DEPRECATED {
   global:
     __system_property_find_nth;
+    __system_property_wait_any;
 };
 
 LIBC_PLATFORM {
   global:
+    __system_properties_init;
+    __system_property_area__; # var
     __system_property_add;
+    __system_property_area_init;
+    __system_property_set_filename;
     __system_property_update;
     android_net_res_stats_get_info_for_net;
     android_net_res_stats_aggregate;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 6afea32..6cc0f32 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -186,9 +186,6 @@
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
-    __system_properties_init;
-    __system_property_area__; # var
-    __system_property_area_init; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_area_serial; # introduced=23
     __system_property_find;
     __system_property_foreach; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
@@ -196,8 +193,6 @@
     __system_property_read;
     __system_property_serial; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_set; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
-    __system_property_set_filename; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
-    __system_property_wait_any; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __timer_create; # arm x86 mips
     __timer_delete; # arm x86 mips
     __timer_getoverrun; # arm x86 mips
@@ -1564,11 +1559,16 @@
 LIBC_DEPRECATED {
   global:
     __system_property_find_nth;
+    __system_property_wait_any;
 };
 
 LIBC_PLATFORM {
   global:
+    __system_properties_init;
+    __system_property_area__; # var
     __system_property_add;
+    __system_property_area_init;
+    __system_property_set_filename;
     __system_property_update;
     android_net_res_stats_get_info_for_net;
     android_net_res_stats_aggregate;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index d67c0f3..91d80e0 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -182,9 +182,6 @@
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
-    __system_properties_init;
-    __system_property_area__; # var
-    __system_property_area_init; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_area_serial; # introduced=23
     __system_property_find;
     __system_property_foreach; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
@@ -192,8 +189,6 @@
     __system_property_read;
     __system_property_serial; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_set; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
-    __system_property_set_filename; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
-    __system_property_wait_any; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __timer_create; # arm x86 mips
     __timer_delete; # arm x86 mips
     __timer_getoverrun; # arm x86 mips
@@ -1379,11 +1374,16 @@
 LIBC_DEPRECATED {
   global:
     __system_property_find_nth;
+    __system_property_wait_any;
 };
 
 LIBC_PLATFORM {
   global:
+    __system_properties_init;
+    __system_property_area__; # var
     __system_property_add;
+    __system_property_area_init;
+    __system_property_set_filename;
     __system_property_update;
     android_net_res_stats_get_info_for_net;
     android_net_res_stats_aggregate;
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index 74d0171..4953380 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -130,9 +130,6 @@
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
-    __system_properties_init;
-    __system_property_area__; # var
-    __system_property_area_init; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_area_serial; # introduced=23
     __system_property_find;
     __system_property_foreach; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
@@ -140,8 +137,6 @@
     __system_property_read;
     __system_property_serial; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_set; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
-    __system_property_set_filename; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
-    __system_property_wait_any; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __umask_chk; # introduced-arm=18 introduced-arm64=21 introduced-mips=18 introduced-mips64=21 introduced-x86=18 introduced-x86_64=21
     __vsnprintf_chk; # introduced-arm=17 introduced-arm64=21 introduced-mips=17 introduced-mips64=21 introduced-x86=17 introduced-x86_64=21
     __vsprintf_chk; # introduced-arm=17 introduced-arm64=21 introduced-mips=17 introduced-mips64=21 introduced-x86=17 introduced-x86_64=21
@@ -1255,11 +1250,16 @@
 LIBC_DEPRECATED {
   global:
     __system_property_find_nth;
+    __system_property_wait_any;
 };
 
 LIBC_PLATFORM {
   global:
+    __system_properties_init;
+    __system_property_area__; # var
     __system_property_add;
+    __system_property_area_init;
+    __system_property_set_filename;
     __system_property_update;
     android_net_res_stats_get_info_for_net;
     android_net_res_stats_aggregate;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index bbba189..7a72fca 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -182,9 +182,6 @@
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
-    __system_properties_init;
-    __system_property_area__; # var
-    __system_property_area_init; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_area_serial; # introduced=23
     __system_property_find;
     __system_property_foreach; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
@@ -192,8 +189,6 @@
     __system_property_read;
     __system_property_serial; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_set; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
-    __system_property_set_filename; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
-    __system_property_wait_any; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __timer_create; # arm x86 mips
     __timer_delete; # arm x86 mips
     __timer_getoverrun; # arm x86 mips
@@ -1378,11 +1373,16 @@
 LIBC_DEPRECATED {
   global:
     __system_property_find_nth;
+    __system_property_wait_any;
 };
 
 LIBC_PLATFORM {
   global:
+    __system_properties_init;
+    __system_property_area__; # var
     __system_property_add;
+    __system_property_area_init;
+    __system_property_set_filename;
     __system_property_update;
     android_net_res_stats_get_info_for_net;
     android_net_res_stats_aggregate;
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index 74d0171..4953380 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -130,9 +130,6 @@
     __sym_ntop;
     __sym_ntos;
     __sym_ston;
-    __system_properties_init;
-    __system_property_area__; # var
-    __system_property_area_init; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_area_serial; # introduced=23
     __system_property_find;
     __system_property_foreach; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
@@ -140,8 +137,6 @@
     __system_property_read;
     __system_property_serial; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __system_property_set; # introduced-arm=12 introduced-arm64=21 introduced-mips=12 introduced-mips64=21 introduced-x86=12 introduced-x86_64=21
-    __system_property_set_filename; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
-    __system_property_wait_any; # introduced-arm=19 introduced-arm64=21 introduced-mips=19 introduced-mips64=21 introduced-x86=19 introduced-x86_64=21
     __umask_chk; # introduced-arm=18 introduced-arm64=21 introduced-mips=18 introduced-mips64=21 introduced-x86=18 introduced-x86_64=21
     __vsnprintf_chk; # introduced-arm=17 introduced-arm64=21 introduced-mips=17 introduced-mips64=21 introduced-x86=17 introduced-x86_64=21
     __vsprintf_chk; # introduced-arm=17 introduced-arm64=21 introduced-mips=17 introduced-mips64=21 introduced-x86=17 introduced-x86_64=21
@@ -1255,11 +1250,16 @@
 LIBC_DEPRECATED {
   global:
     __system_property_find_nth;
+    __system_property_wait_any;
 };
 
 LIBC_PLATFORM {
   global:
+    __system_properties_init;
+    __system_property_area__; # var
     __system_property_add;
+    __system_property_area_init;
+    __system_property_set_filename;
     __system_property_update;
     android_net_res_stats_get_info_for_net;
     android_net_res_stats_aggregate;
diff --git a/libc/private/libc_logging.h b/libc/private/libc_logging.h
index 49a5a3c..d3e4140 100644
--- a/libc/private/libc_logging.h
+++ b/libc/private/libc_logging.h
@@ -97,6 +97,14 @@
 #endif
 int __libc_write_log(int pri, const char* _Nonnull tag, const char* _Nonnull msg);
 
+#define CHECK(predicate) \
+  do { \
+    if (!(predicate)) { \
+      __libc_fatal("%s:%d: %s CHECK '" #predicate "' failed", \
+          __FILE__, __LINE__, __FUNCTION__); \
+    } \
+  } while(0)
+
 __END_DECLS
 
 #endif
diff --git a/linker/Android.bp b/linker/Android.bp
index aab05b4..a43f8b3 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -39,29 +39,35 @@
             srcs: ["arch/arm/begin.S"],
 
             cflags: ["-D__work_around_b_24465209__"],
+            ldflags: ["-Wl,-dynamic-linker,/system/bin/linker"],
         },
         arm64: {
             srcs: ["arch/arm64/begin.S"],
+            ldflags: ["-Wl,-dynamic-linker,/system/bin/linker64"],
         },
         x86: {
             srcs: ["arch/x86/begin.c"],
 
             cflags: ["-D__work_around_b_24465209__"],
+            ldflags: ["-Wl,-dynamic-linker,/system/bin/linker"],
         },
         x86_64: {
             srcs: ["arch/x86_64/begin.S"],
+            ldflags: ["-Wl,-dynamic-linker,/system/bin/linker64"],
         },
         mips: {
             srcs: [
                 "arch/mips/begin.S",
                 "linker_mips.cpp",
             ],
+            ldflags: ["-Wl,-dynamic-linker,/system/bin/linker"],
         },
         mips64: {
             srcs: [
                 "arch/mips64/begin.S",
                 "linker_mips.cpp",
             ],
+            ldflags: ["-Wl,-dynamic-linker,/system/bin/linker64"],
         },
     },
 
diff --git a/linker/linker_debug.h b/linker/linker_debug.h
index 5af9929..42796e9 100644
--- a/linker/linker_debug.h
+++ b/linker/linker_debug.h
@@ -59,13 +59,6 @@
 
 __LIBC_HIDDEN__ extern int g_ld_debug_verbosity;
 
-#define CHECK(predicate) { \
-    if (!(predicate)) { \
-      __libc_fatal("%s:%d: %s CHECK '" #predicate "' failed", \
-          __FILE__, __LINE__, __FUNCTION__); \
-    } \
-  }
-
 #if LINKER_DEBUG_TO_LOG
 #define _PRINTVF(v, x...) \
     do { \
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index d52b1d6..d037a18 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -496,7 +496,7 @@
   // see also https://code.google.com/p/android/issues/detail?id=63174
   if (reinterpret_cast<ElfW(Addr)>(&_start) == entry_point) {
     __libc_format_fd(STDOUT_FILENO,
-                     "This is %s, the helper program for shared library executables.\n",
+                     "This is %s, the helper program for dynamic executables.\n",
                      args.argv[0]);
     exit(0);
   }
diff --git a/tests/Android.bp b/tests/Android.bp
index 2ccdbf8..1cca332 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -58,6 +58,7 @@
         "complex_test.cpp",
         "ctype_test.cpp",
         "dirent_test.cpp",
+        "endian_test.cpp",
         "error_test.cpp",
         "eventfd_test.cpp",
         "fcntl_test.cpp",
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index 74c7b51..ee9b2e1 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -24,6 +24,8 @@
 
 #include <string>
 
+#include "utils.h"
+
 extern "C" int main_global_default_serial() {
   return 3370318;
 }
@@ -69,4 +71,19 @@
   ASSERT_EQ(3370318, lib_global_protected_get_serial());
 }
 
+TEST(dl, exec_linker) {
+#if defined(__BIONIC__)
+#if defined(__LP64__)
+  static constexpr const char* kPathToLinker = "/system/bin/linker64";
+#else
+  static constexpr const char* kPathToLinker = "/system/bin/linker";
+#endif
+  ExecTestHelper eth;
+  std::string expected_output = std::string("This is ") + kPathToLinker +
+                                ", the helper program for dynamic executables.\n";
+  eth.SetArgs( { kPathToLinker, nullptr });
+  eth.Run([&]() { execve(kPathToLinker, eth.GetArgs(), eth.GetEnv()); }, 0, expected_output.c_str());
+#endif
+}
+
 // TODO: Add tests for LD_PRELOADs
diff --git a/tests/endian_test.cpp b/tests/endian_test.cpp
new file mode 100644
index 0000000..85d56f0
--- /dev/null
+++ b/tests/endian_test.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 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 <endian.h>
+
+#include <gtest/gtest.h>
+
+static constexpr uint16_t le16 = 0x1234;
+static constexpr uint32_t le32 = 0x12345678;
+static constexpr uint64_t le64 = 0x123456789abcdef0;
+
+static constexpr uint16_t be16 = 0x3412;
+static constexpr uint32_t be32 = 0x78563412;
+static constexpr uint64_t be64 = 0xf0debc9a78563412;
+
+TEST(endian, constants) {
+  ASSERT_TRUE(__LITTLE_ENDIAN == LITTLE_ENDIAN);
+  ASSERT_TRUE(__BIG_ENDIAN == BIG_ENDIAN);
+  ASSERT_TRUE(__BYTE_ORDER == BYTE_ORDER);
+
+#if defined(__BIONIC__)
+  ASSERT_TRUE(_LITTLE_ENDIAN == LITTLE_ENDIAN);
+  ASSERT_TRUE(_BIG_ENDIAN == BIG_ENDIAN);
+  ASSERT_TRUE(_BYTE_ORDER == BYTE_ORDER);
+#endif
+
+  ASSERT_EQ(__LITTLE_ENDIAN, __BYTE_ORDER);
+}
+
+TEST(endian, htons_htonl_htonq_macros) {
+#if defined(__BIONIC__)
+  ASSERT_EQ(be16, htons(le16));
+  ASSERT_EQ(be32, htonl(le32));
+  ASSERT_EQ(be64, htonq(le64));
+#else
+  GTEST_LOG_(INFO) << "glibc doesn't have these macros";
+#endif
+}
+
+TEST(endian, ntohs_ntohl_ntohq_macros) {
+#if defined(__BIONIC__)
+  ASSERT_EQ(le16, ntohs(be16));
+  ASSERT_EQ(le32, ntohl(be32));
+  ASSERT_EQ(le64, ntohq(be64));
+#else
+  GTEST_LOG_(INFO) << "glibc doesn't have these macros";
+#endif
+}
+
+TEST(endian, htobe16_htobe32_htobe64) {
+  ASSERT_EQ(be16, htobe16(le16));
+  ASSERT_EQ(be32, htobe32(le32));
+  ASSERT_EQ(be64, htobe64(le64));
+}
+
+TEST(endian, htole16_htole32_htole64) {
+  ASSERT_EQ(le16, htole16(le16));
+  ASSERT_EQ(le32, htole32(le32));
+  ASSERT_EQ(le64, htole64(le64));
+}
+
+TEST(endian, be16toh_be32toh_be64toh) {
+  ASSERT_EQ(le16, be16toh(be16));
+  ASSERT_EQ(le32, be32toh(be32));
+  ASSERT_EQ(le64, be64toh(be64));
+}
+
+TEST(endian, le16toh_le32toh_le64toh) {
+  ASSERT_EQ(le16, le16toh(le16));
+  ASSERT_EQ(le32, le32toh(le32));
+  ASSERT_EQ(le64, le64toh(le64));
+}
+
+TEST(endian, betoh16_betoh32_betoh64) {
+#if defined(__BIONIC__)
+  ASSERT_EQ(le16, betoh16(be16));
+  ASSERT_EQ(le32, betoh32(be32));
+  ASSERT_EQ(le64, betoh64(be64));
+#else
+  GTEST_LOG_(INFO) << "glibc doesn't have these macros";
+#endif
+}
+
+TEST(endian, letoh16_letoh32_letoh64) {
+#if defined(__BIONIC__)
+  ASSERT_EQ(le16, letoh16(le16));
+  ASSERT_EQ(le32, letoh32(le32));
+  ASSERT_EQ(le64, letoh64(le64));
+#else
+  GTEST_LOG_(INFO) << "glibc doesn't have these macros";
+#endif
+}
diff --git a/tests/netinet_in_test.cpp b/tests/netinet_in_test.cpp
index a337770..c0d3bc8 100644
--- a/tests/netinet_in_test.cpp
+++ b/tests/netinet_in_test.cpp
@@ -20,6 +20,16 @@
 
 #include <gtest/gtest.h>
 
+#include <android-base/macros.h>
+
+static constexpr uint16_t le16 = 0x1234;
+static constexpr uint32_t le32 = 0x12345678;
+static constexpr uint64_t le64 = 0x123456789abcdef0;
+
+static constexpr uint16_t be16 = 0x3412;
+static constexpr uint32_t be32 = 0x78563412;
+static constexpr uint64_t be64 = 0xf0debc9a78563412;
+
 TEST(netinet_in, bindresvport) {
   // This isn't something we can usually test, so just check the symbol's there.
   ASSERT_EQ(-1, bindresvport(-1, nullptr));
@@ -34,3 +44,35 @@
   in6_addr loopback = IN6ADDR_LOOPBACK_INIT;
   ASSERT_EQ(0, memcmp(&loopback, &in6addr_loopback, sizeof(in6addr_loopback)));
 }
+
+TEST(netinet_in, htons_function) {
+  ASSERT_EQ(be16, (htons)(le16));
+}
+
+TEST(netinet_in, htonl_function) {
+  ASSERT_EQ(be32, (htonl)(le32));
+}
+
+TEST(netinet_in, htonq_macro) {
+#if defined(__BIONIC__)
+  ASSERT_EQ(be64, htonq(le64));
+#else
+  UNUSED(be64);
+#endif
+}
+
+TEST(netinet_in, ntohs_function) {
+  ASSERT_EQ(le16, (ntohs)(be16));
+}
+
+TEST(netinet_in, ntohl_function) {
+  ASSERT_EQ(le32, (ntohl)(be32));
+}
+
+TEST(netinet_in, ntohq_macro) {
+#if defined(__BIONIC__)
+  ASSERT_EQ(le64, ntohq(be64));
+#else
+  UNUSED(le64);
+#endif
+}