Merge "__cfi_slowpath[_diag] are available to NDK and VNDK clients"
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp
index 3f95aa1..0edba65 100644
--- a/benchmarks/Android.bp
+++ b/benchmarks/Android.bp
@@ -35,6 +35,17 @@
         "time_benchmark.cpp",
         "unistd_benchmark.cpp",
     ],
+    static_libs: ["libBionicBenchmarksUtils"],
+}
+
+cc_defaults {
+    name: "bionic-benchmarks-extras-defaults",
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wunused",
+    ],
 }
 
 // Build benchmarks for the device (with bionic's .so). Run with:
@@ -63,3 +74,19 @@
         },
     },
 }
+
+cc_library_static {
+    name: "libBionicBenchmarksUtils",
+    defaults: ["bionic-benchmarks-extras-defaults"],
+    srcs: ["util.cpp"],
+    host_supported: true,
+}
+
+cc_test {
+    name: "bionic-benchmarks-tests",
+    defaults: ["bionic-benchmarks-extras-defaults"],
+    srcs: [
+        "tests/benchmark_test.cpp",
+    ],
+    static_libs: ["libBionicBenchmarksUtils"],
+}
diff --git a/benchmarks/string_benchmark.cpp b/benchmarks/string_benchmark.cpp
index 86a7c35..2ab65a8 100644
--- a/benchmarks/string_benchmark.cpp
+++ b/benchmarks/string_benchmark.cpp
@@ -18,188 +18,246 @@
 #include <string.h>
 
 #include <benchmark/benchmark.h>
+#include "util.h"
 
 constexpr auto KB = 1024;
 
-#define AT_COMMON_SIZES \
-    Arg(8)->Arg(64)->Arg(512)->Arg(1*KB)->Arg(8*KB)->Arg(16*KB)->Arg(32*KB)->Arg(64*KB)
+// NOTE: these constants are temporary replacements for AT_COMMON_SIZES until
+// the new interface for Bionic benchmarks is implemented.
 
-// TODO: test unaligned operation too? (currently everything will be 8-byte aligned by malloc.)
+// Set all four to 0 to test normal alignment.
+#define AT_SRC_ALIGN 0
+#define AT_DST_ALIGN 0
+
+#define AT_ALIGNED_TWOBUF \
+    Args({(8), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(64), AT_SRC_ALIGN, AT_DST_ALIGN})-> \
+    Args({(512), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(1*KB), AT_SRC_ALIGN, AT_DST_ALIGN})-> \
+    Args({(8*KB), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(16*KB), AT_SRC_ALIGN, AT_DST_ALIGN})-> \
+    Args({(32*KB), AT_SRC_ALIGN, AT_DST_ALIGN})->Args({(64*KB), AT_SRC_ALIGN, AT_DST_ALIGN})
+
+#define AT_ALIGNED_ONEBUF \
+    Args({(8), AT_SRC_ALIGN})->Args({(64), AT_SRC_ALIGN})->Args({(512), AT_SRC_ALIGN})-> \
+    Args({(1*KB), AT_SRC_ALIGN})->Args({(8*KB), AT_SRC_ALIGN})->Args({(16*KB), AT_SRC_ALIGN})-> \
+    Args({(32*KB), AT_SRC_ALIGN})->Args({(64*KB), AT_SRC_ALIGN})
 
 static void BM_string_memcmp(benchmark::State& state) {
   const size_t nbytes = state.range(0);
-  char* src = new char[nbytes]; char* dst = new char[nbytes];
-  memset(src, 'x', nbytes);
-  memset(dst, 'x', nbytes);
+  const size_t src_alignment = state.range(1);
+  const size_t dst_alignment = state.range(2);
+
+  std::vector<char> src;
+  std::vector<char> dst;
+  char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
+  char* dst_aligned = GetAlignedPtrFilled(&dst, dst_alignment, nbytes, 'x');
 
   volatile int c __attribute__((unused)) = 0;
   while (state.KeepRunning()) {
-    c += memcmp(dst, src, nbytes);
+    c += memcmp(dst_aligned, src_aligned, nbytes);
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
-  delete[] src;
-  delete[] dst;
 }
-BENCHMARK(BM_string_memcmp)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_memcmp)->AT_ALIGNED_TWOBUF;
 
 static void BM_string_memcpy(benchmark::State& state) {
   const size_t nbytes = state.range(0);
-  char* src = new char[nbytes]; char* dst = new char[nbytes];
-  memset(src, 'x', nbytes);
+  const size_t src_alignment = state.range(1);
+  const size_t dst_alignment = state.range(2);
+
+  std::vector<char> src;
+  std::vector<char> dst;
+  char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
+  char* dst_aligned = GetAlignedPtr(&dst, dst_alignment, nbytes);
 
   while (state.KeepRunning()) {
-    memcpy(dst, src, nbytes);
+    memcpy(dst_aligned, src_aligned, nbytes);
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
-  delete[] src;
-  delete[] dst;
 }
-BENCHMARK(BM_string_memcpy)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_memcpy)->AT_ALIGNED_TWOBUF;
 
 static void BM_string_memmove_non_overlapping(benchmark::State& state) {
   const size_t nbytes = state.range(0);
-  std::vector<char> src(nbytes, 'x');
-  std::vector<char> dst(nbytes, 'x');
+  const size_t src_alignment = state.range(1);
+  const size_t dst_alignment = state.range(2);
+
+  std::vector<char> src;
+  std::vector<char> dst;
+  char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
+  char* dst_aligned = GetAlignedPtrFilled(&dst, dst_alignment, nbytes, 'y');
 
   while (state.KeepRunning()) {
-    memmove(dst.data(), src.data(), nbytes);
+    memmove(dst_aligned, src_aligned, nbytes);
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
 }
-BENCHMARK(BM_string_memmove_non_overlapping)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_memmove_non_overlapping)->AT_ALIGNED_TWOBUF;
 
 static void BM_string_memmove_overlap_dst_before_src(benchmark::State& state) {
   const size_t nbytes = state.range(0);
-  std::vector<char> buf(nbytes + 1, 'x');
+  const size_t alignment = state.range(1);
+
+  std::vector<char> buf(3 * alignment + nbytes + 1, 'x');
+  char* buf_aligned = GetAlignedPtrFilled(&buf, alignment, nbytes + 1, 'x');
 
   while (state.KeepRunning()) {
-    memmove(buf.data(), buf.data() + 1, nbytes); // Worst-case overlap.
+    memmove(buf_aligned, buf_aligned + 1, nbytes);  // Worst-case overlap.
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
 }
-BENCHMARK(BM_string_memmove_overlap_dst_before_src)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_memmove_overlap_dst_before_src)->AT_ALIGNED_ONEBUF;
 
 static void BM_string_memmove_overlap_src_before_dst(benchmark::State& state) {
   const size_t nbytes = state.range(0);
-  std::vector<char> buf(nbytes + 1, 'x');
+  const size_t alignment = state.range(1);
+
+  std::vector<char> buf;
+  char* buf_aligned = GetAlignedPtrFilled(&buf, alignment, nbytes + 1, 'x');
 
   while (state.KeepRunning()) {
-    memmove(buf.data() + 1, buf.data(), nbytes); // Worst-case overlap.
+    memmove(buf_aligned + 1, buf_aligned, nbytes);  // Worst-case overlap.
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
 }
-BENCHMARK(BM_string_memmove_overlap_src_before_dst)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_memmove_overlap_src_before_dst)->AT_ALIGNED_ONEBUF;
 
 static void BM_string_memset(benchmark::State& state) {
   const size_t nbytes = state.range(0);
-  char* dst = new char[nbytes];
+  const size_t alignment = state.range(1);
+
+  std::vector<char> buf;
+  char* buf_aligned = GetAlignedPtr(&buf, alignment, nbytes + 1);
 
   while (state.KeepRunning()) {
-    memset(dst, 0, nbytes);
+    memset(buf_aligned, 0, nbytes);
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
-  delete[] dst;
 }
-BENCHMARK(BM_string_memset)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_memset)->AT_ALIGNED_ONEBUF;
 
 static void BM_string_strlen(benchmark::State& state) {
   const size_t nbytes = state.range(0);
-  char* s = new char[nbytes];
-  memset(s, 'x', nbytes);
-  s[nbytes - 1] = 0;
+  const size_t alignment = state.range(1);
+
+  std::vector<char> buf;
+  char* buf_aligned = GetAlignedPtrFilled(&buf, alignment, nbytes + 1, 'x');
+  buf_aligned[nbytes - 1] = '\0';
 
   volatile int c __attribute__((unused)) = 0;
   while (state.KeepRunning()) {
-    c += strlen(s);
+    c += strlen(buf_aligned);
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
-  delete[] s;
 }
-BENCHMARK(BM_string_strlen)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_strlen)->AT_ALIGNED_ONEBUF;
 
 static void BM_string_strcat_copy_only(benchmark::State& state) {
   const size_t nbytes = state.range(0);
-  std::vector<char> src(nbytes, 'x');
-  std::vector<char> dst(nbytes + 2);
-  src[nbytes - 1] = '\0';
-  dst[0] = 'y';
-  dst[1] = 'y';
-  dst[2] = '\0';
+  const size_t src_alignment = state.range(1);
+  const size_t dst_alignment = state.range(2);
+
+  std::vector<char> src;
+  std::vector<char> dst;
+  char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
+  char* dst_aligned = GetAlignedPtr(&dst, dst_alignment, nbytes + 2);
+  src_aligned[nbytes - 1] = '\0';
+  dst_aligned[0] = 'y';
+  dst_aligned[1] = 'y';
+  dst_aligned[2] = '\0';
 
   while (state.KeepRunning()) {
-    strcat(dst.data(), src.data());
-    dst[2] = '\0';
+    strcat(dst_aligned, src_aligned);
+    dst_aligned[2] = '\0';
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
 }
-BENCHMARK(BM_string_strcat_copy_only)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_strcat_copy_only)->AT_ALIGNED_TWOBUF;
 
 static void BM_string_strcat_seek_only(benchmark::State& state) {
   const size_t nbytes = state.range(0);
-  std::vector<char> src(3, 'x');
-  std::vector<char> dst(nbytes + 2, 'y');
-  src[2] = '\0';
-  dst[nbytes - 1] = '\0';
+  const size_t src_alignment = state.range(1);
+  const size_t dst_alignment = state.range(2);
+
+  std::vector<char> src;
+  std::vector<char> dst;
+  char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, 3, 'x');
+  char* dst_aligned = GetAlignedPtrFilled(&dst, dst_alignment, nbytes + 2, 'y');
+  src_aligned[2] = '\0';
+  dst_aligned[nbytes - 1] = '\0';
 
   while (state.KeepRunning()) {
-    strcat(dst.data(), src.data());
-    dst[nbytes - 1] = '\0';
+    strcat(dst_aligned, src_aligned);
+    dst_aligned[nbytes - 1] = '\0';
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
 }
-BENCHMARK(BM_string_strcat_seek_only)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_strcat_seek_only)->AT_ALIGNED_TWOBUF;
 
 static void BM_string_strcat_half_copy_half_seek(benchmark::State& state) {
   const size_t nbytes = state.range(0);
-  std::vector<char> src(nbytes / 2, 'x');
-  std::vector<char> dst(nbytes / 2, 'y');
-  src[nbytes / 2 - 1] = '\0';
-  dst[nbytes / 2 - 1] = '\0';
+  const size_t src_alignment = state.range(1);
+  const size_t dst_alignment = state.range(2);
+
+  std::vector<char> src;
+  std::vector<char> dst;
+  char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes / 2, 'x');
+  char* dst_aligned = GetAlignedPtrFilled(&dst, dst_alignment, nbytes, 'y');
+  src_aligned[nbytes / 2 - 1] = '\0';
+  dst_aligned[nbytes / 2 - 1] = '\0';
 
   while (state.KeepRunning()) {
-    strcat(dst.data(), src.data());
-    dst[nbytes / 2 - 1] = '\0';
+    strcat(dst_aligned, src_aligned);
+    dst_aligned[nbytes / 2 - 1] = '\0';
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
 }
-BENCHMARK(BM_string_strcat_half_copy_half_seek)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_strcat_half_copy_half_seek)->AT_ALIGNED_TWOBUF;
 
 static void BM_string_strcpy(benchmark::State& state) {
   const size_t nbytes = state.range(0);
-  std::vector<char> src(nbytes, 'x');
-  std::vector<char> dst(nbytes);
-  src[nbytes - 1] = '\0';
+  const size_t src_alignment = state.range(1);
+  const size_t dst_alignment = state.range(2);
+
+  std::vector<char> src;
+  std::vector<char> dst;
+  char* src_aligned = GetAlignedPtrFilled(&src, src_alignment, nbytes, 'x');
+  char* dst_aligned = GetAlignedPtr(&dst, dst_alignment, nbytes);
+  src_aligned[nbytes - 1] = '\0';
 
   while (state.KeepRunning()) {
-    strcpy(dst.data(), src.data());
+    strcpy(dst_aligned, src_aligned);
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
 }
-BENCHMARK(BM_string_strcpy)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_strcpy)->AT_ALIGNED_TWOBUF;
 
 static void BM_string_strcmp(benchmark::State& state) {
   const size_t nbytes = state.range(0);
-  std::vector<char> s1(nbytes, 'x');
-  std::vector<char> s2(nbytes, 'x');
-  s1[nbytes - 1] = '\0';
-  s2[nbytes - 1] = '\0';
+  const size_t s1_alignment = state.range(1);
+  const size_t s2_alignment = state.range(2);
+
+  std::vector<char> s1;
+  std::vector<char> s2;
+  char* s1_aligned = GetAlignedPtrFilled(&s1, s1_alignment, nbytes, 'x');
+  char* s2_aligned = GetAlignedPtrFilled(&s2, s2_alignment, nbytes, 'x');
+  s1_aligned[nbytes - 1] = '\0';
+  s2_aligned[nbytes - 1] = '\0';
 
   volatile int c __attribute__((unused));
   while (state.KeepRunning()) {
-    c = strcmp(s1.data(), s2.data());
+    c = strcmp(s1_aligned, s2_aligned);
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
 }
-BENCHMARK(BM_string_strcmp)->AT_COMMON_SIZES;
+BENCHMARK(BM_string_strcmp)->AT_ALIGNED_TWOBUF;
diff --git a/benchmarks/tests/benchmark_test.cpp b/benchmarks/tests/benchmark_test.cpp
new file mode 100644
index 0000000..df7b686
--- /dev/null
+++ b/benchmarks/tests/benchmark_test.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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 <gtest/gtest.h>
+#include <util.h>
+
+TEST(benchmark, memory_align) {
+  std::vector<char> buf(100);
+  for (size_t alignment = 1; alignment <= 32; alignment *= 2) {
+    for (size_t or_mask = 0; or_mask < alignment; ++or_mask) {
+      uintptr_t aligned_ptr = reinterpret_cast<uintptr_t>(GetAlignedMemory(buf.data(), alignment,
+                                                                           or_mask));
+      ASSERT_EQ(aligned_ptr % alignment, or_mask);
+      ASSERT_EQ(aligned_ptr & alignment, alignment);
+    }
+  }
+}
+
+TEST(benchmark, ptr_align) {
+  std::vector<char> buf;
+  for (size_t alignment = 1; alignment <= 2048; alignment *= 2) {
+    uintptr_t aligned_ptr = reinterpret_cast<uintptr_t>(GetAlignedPtr(&buf, alignment, 100));
+    ASSERT_EQ(aligned_ptr & alignment, alignment);
+    ASSERT_EQ(aligned_ptr & (alignment - 1), 0u);
+  }
+}
diff --git a/benchmarks/util.cpp b/benchmarks/util.cpp
new file mode 100644
index 0000000..d9641cf
--- /dev/null
+++ b/benchmarks/util.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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 "util.h"
+
+#include <sched.h>
+#include <stdio.h>
+#include <string.h>
+#include <cstdlib>
+#include <vector>
+
+// This function returns a pointer less than 2 * alignment + or_mask bytes into the array.
+char *GetAlignedMemory(char *orig_ptr, size_t alignment, size_t or_mask) {
+  if ((alignment & (alignment - 1)) != 0) {
+    fprintf(stderr, "warning: alignment passed into GetAlignedMemory is not a power of two.\n");
+    std::abort();
+  }
+  if (or_mask > alignment) {
+    fprintf(stderr, "warning: or_mask passed into GetAlignedMemory is too high.\n");
+    std::abort();
+  }
+  uintptr_t ptr = reinterpret_cast<uintptr_t>(orig_ptr);
+  if (alignment > 0) {
+    // When setting the alignment, set it to exactly the alignment chosen.
+    // The pointer returned will be guaranteed not to be aligned to anything
+    // more than that.
+    ptr += alignment - (ptr & (alignment - 1));
+    ptr |= alignment | or_mask;
+  }
+
+  return reinterpret_cast<char*>(ptr);
+}
+
+char *GetAlignedPtr(std::vector<char>* buf, size_t alignment, size_t nbytes) {
+  buf->resize(nbytes + 3 * alignment);
+  return GetAlignedMemory(buf->data(), alignment, 0);
+}
+
+char *GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte) {
+  char* buf_aligned = GetAlignedPtr(buf, alignment, nbytes);
+  memset(buf_aligned, fill_byte, nbytes);
+  return buf_aligned;
+}
+
+#if defined(__APPLE__)
+
+// Darwin doesn't support this, so do nothing.
+bool LockToCPU(int) {
+  return false;
+}
+
+#else
+
+bool LockToCPU(int cpu_to_lock) {
+  cpu_set_t cpuset;
+
+  CPU_ZERO(&cpuset);
+  if (sched_getaffinity(0, sizeof(cpuset), &cpuset) != 0) {
+    perror("sched_getaffinity failed");
+    return false;
+  }
+
+  if (cpu_to_lock < 0) {
+    // Lock to the last active core we find.
+    for (int i = 0; i < CPU_SETSIZE; i++) {
+      if (CPU_ISSET(i, &cpuset)) {
+        cpu_to_lock = i;
+      }
+    }
+  } else if (!CPU_ISSET(cpu_to_lock, &cpuset)) {
+    printf("Cpu %d does not exist.\n", cpu_to_lock);
+    return false;
+  }
+
+  if (cpu_to_lock < 0) {
+    printf("Cannot find any valid cpu to lock.\n");
+    return false;
+  }
+
+  CPU_ZERO(&cpuset);
+  CPU_SET(cpu_to_lock, &cpuset);
+  if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) {
+    perror("sched_setaffinity failed");
+    return false;
+  }
+
+  return true;
+}
+
+#endif
diff --git a/benchmarks/util.h b/benchmarks/util.h
new file mode 100644
index 0000000..bd3d515
--- /dev/null
+++ b/benchmarks/util.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#ifndef _BIONIC_BENCHMARKS_UTIL_H_
+#define _BIONIC_BENCHMARKS_UTIL_H_
+
+#include <vector>
+
+// This function returns a pointer less than 2 * alignment + or_mask bytes into the array.
+char *GetAlignedMemory(char *orig_ptr, size_t alignment, size_t or_mask);
+
+char *GetAlignedPtr(std::vector<char>* buf, size_t alignment, size_t nbytes);
+
+char *GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte);
+
+bool LockToCPU(int cpu_to_lock);
+
+#endif // _BIONIC_BENCHMARKS_UTIL_H
diff --git a/libc/Android.bp b/libc/Android.bp
index cd2a727..845945a 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1330,6 +1330,13 @@
 cc_library_static {
     defaults: ["libc_defaults"],
     srcs: [
+        "bionic/NetdClientDispatch.cpp",
+        "bionic/__cmsg_nxthdr.cpp",
+        "bionic/__errno.cpp",
+        "bionic/__gnu_basename.cpp",
+        "bionic/__libc_current_sigrtmax.cpp",
+        "bionic/__libc_current_sigrtmin.cpp",
+        "bionic/__set_errno.cpp",
         "bionic/abort.cpp",
         "bionic/accept.cpp",
         "bionic/accept4.cpp",
@@ -1352,7 +1359,6 @@
         "bionic/clock_nanosleep.cpp",
         "bionic/clone.cpp",
         "bionic/close.cpp",
-        "bionic/__cmsg_nxthdr.cpp",
         "bionic/connect.cpp",
         "bionic/ctype.cpp",
         "bionic/dirent.cpp",
@@ -1361,7 +1367,6 @@
         "bionic/epoll_create.cpp",
         "bionic/epoll_pwait.cpp",
         "bionic/epoll_wait.cpp",
-        "bionic/__errno.cpp",
         "bionic/error.cpp",
         "bionic/eventfd_read.cpp",
         "bionic/eventfd_write.cpp",
@@ -1387,7 +1392,6 @@
         "bionic/getpid.cpp",
         "bionic/getpriority.cpp",
         "bionic/gettid.cpp",
-        "bionic/__gnu_basename.cpp",
         "bionic/grp_pwd.cpp",
         "bionic/ifaddrs.cpp",
         "bionic/inotify_init.cpp",
@@ -1395,8 +1399,6 @@
         "bionic/langinfo.cpp",
         "bionic/lchown.cpp",
         "bionic/lfs64_support.cpp",
-        "bionic/__libc_current_sigrtmax.cpp",
-        "bionic/__libc_current_sigrtmin.cpp",
         "bionic/libc_init_common.cpp",
         "bionic/libgen.cpp",
         "bionic/link.cpp",
@@ -1415,9 +1417,8 @@
         "bionic/mknod.cpp",
         "bionic/mntent.cpp",
         "bionic/mremap.cpp",
-        "bionic/netdb.cpp",
-        "bionic/NetdClientDispatch.cpp",
         "bionic/net_if.cpp",
+        "bionic/netdb.cpp",
         "bionic/netinet_in.cpp",
         "bionic/nl_types.cpp",
         "bionic/open.cpp",
@@ -1444,7 +1445,6 @@
         "bionic/semaphore.cpp",
         "bionic/send.cpp",
         "bionic/setegid.cpp",
-        "bionic/__set_errno.cpp",
         "bionic/seteuid.cpp",
         "bionic/setpgrp.cpp",
         "bionic/sigaction.cpp",
@@ -1470,21 +1470,24 @@
         "bionic/socket.cpp",
         "bionic/stat.cpp",
         "bionic/statvfs.cpp",
+        "bionic/stdlib_l.cpp",
         "bionic/strchrnul.cpp",
         "bionic/strerror.cpp",
         "bionic/strerror_r.cpp",
+        "bionic/string_l.cpp",
+        "bionic/strings_l.cpp",
         "bionic/strsignal.cpp",
         "bionic/strtold.cpp",
         "bionic/symlink.cpp",
         "bionic/sync_file_range.cpp",
-        "bionic/sysinfo.cpp",
-        "bionic/syslog.cpp",
         "bionic/sys_msg.cpp",
         "bionic/sys_sem.cpp",
         "bionic/sys_shm.cpp",
         "bionic/sys_siglist.c",
         "bionic/sys_signame.c",
         "bionic/sys_time.cpp",
+        "bionic/sysinfo.cpp",
+        "bionic/syslog.cpp",
         "bionic/system_properties.cpp",
         "bionic/tdestroy.cpp",
         "bionic/termios.cpp",
@@ -1494,6 +1497,7 @@
         "bionic/unlink.cpp",
         "bionic/wait.cpp",
         "bionic/wchar.cpp",
+        "bionic/wchar_l.cpp",
         "bionic/wcstod.cpp",
         "bionic/wctype.cpp",
         "bionic/wmempcpy.cpp",
diff --git a/libc/NOTICE b/libc/NOTICE
index c74811c..060ece1 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -2907,6 +2907,25 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 1996, David Mazieres <dm@uun.org>
+Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+-------------------------------------------------------------------
+
 Copyright (c) 1996-1998, 2008 Theo de Raadt
 Copyright (c) 1997, 2008-2009 Todd C. Miller
 
@@ -5384,32 +5403,6 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 2013 David Chisnall
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
 Copyright (c) 2013 The NetBSD Foundation, Inc.
 All rights reserved.
 
diff --git a/libc/bionic/locale.cpp b/libc/bionic/locale.cpp
index 38e15b7..08c9401 100644
--- a/libc/bionic/locale.cpp
+++ b/libc/bionic/locale.cpp
@@ -37,7 +37,15 @@
 
 #include "private/bionic_macros.h"
 
+#if defined(__BIONIC_BUILD_FOR_ANDROID_SUPPORT)
+#define USE_TLS_SLOT 0
+#else
+#define USE_TLS_SLOT 1
+#endif
+
+#if USE_TLS_SLOT
 #include "bionic/pthread_internal.h"
+#endif
 
 // We only support two locales, the "C" locale (also known as "POSIX"),
 // and the "C.UTF-8" locale (also known as "en_US.UTF-8").
@@ -70,6 +78,10 @@
   }
 }
 
+#if !USE_TLS_SLOT
+static thread_local locale_t g_current_locale;
+#endif
+
 static pthread_once_t g_locale_once = PTHREAD_ONCE_INIT;
 static lconv g_locale;
 
@@ -163,9 +175,16 @@
   return const_cast<char*>(__bionic_current_locale_is_utf8 ? "C.UTF-8" : "C");
 }
 
+static locale_t* get_current_locale_ptr() {
+#if USE_TLS_SLOT
+  return &__get_bionic_tls().locale;
+#else
+  return &g_current_locale;
+#endif
+}
+
 locale_t uselocale(locale_t new_locale) {
-  locale_t* locale_storage = &__get_bionic_tls().locale;
-  locale_t old_locale = *locale_storage;
+  locale_t old_locale = *get_current_locale_ptr();
 
   // If this is the first call to uselocale(3) on this thread, we return LC_GLOBAL_LOCALE.
   if (old_locale == NULL) {
@@ -173,64 +192,8 @@
   }
 
   if (new_locale != NULL) {
-    *locale_storage = new_locale;
+    *get_current_locale_ptr() = new_locale;
   }
 
   return old_locale;
 }
-
-int strcasecmp_l(const char* s1, const char* s2, locale_t) {
-  return strcasecmp(s1, s2);
-}
-
-int strcoll_l(const char* s1, const char* s2, locale_t) {
-  return strcoll(s1, s2);
-}
-
-char* strerror_l(int error, locale_t) {
-  return strerror(error);
-}
-
-int strncasecmp_l(const char* s1, const char* s2, size_t n, locale_t) {
-  return strncasecmp(s1, s2, n);
-}
-
-double strtod_l(const char* s, char** end_ptr, locale_t) {
-  return strtod(s, end_ptr);
-}
-
-float strtof_l(const char* s, char** end_ptr, locale_t) {
-  return strtof(s, end_ptr);
-}
-
-long strtol_l(const char* s, char** end_ptr, int base, locale_t) {
-  return strtol(s, end_ptr, base);
-}
-
-long double strtold_l(const char* s, char** end_ptr, locale_t) {
-  return strtold(s, end_ptr);
-}
-
-long long strtoll_l(const char* s, char** end_ptr, int base, locale_t) {
-  return strtoll(s, end_ptr, base);
-}
-
-unsigned long strtoul_l(const char* s, char** end_ptr, int base, locale_t) {
-  return strtoul(s, end_ptr, base);
-}
-
-unsigned long long strtoull_l(const char* s, char** end_ptr, int base, locale_t) {
-  return strtoull(s, end_ptr, base);
-}
-
-size_t strxfrm_l(char* dst, const char* src, size_t n, locale_t) {
-  return strxfrm(dst, src, n);
-}
-
-int wcscasecmp_l(const wchar_t* ws1, const wchar_t* ws2, locale_t) {
-  return wcscasecmp(ws1, ws2);
-}
-
-int wcsncasecmp_l(const wchar_t* ws1, const wchar_t* ws2, size_t n, locale_t) {
-  return wcsncasecmp(ws1, ws2, n);
-}
diff --git a/libc/bionic/stdlib_l.cpp b/libc/bionic/stdlib_l.cpp
new file mode 100644
index 0000000..18e9f86
--- /dev/null
+++ b/libc/bionic/stdlib_l.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <xlocale.h>
+
+double strtod_l(const char* s, char** end_ptr, locale_t) {
+  return strtod(s, end_ptr);
+}
+
+float strtof_l(const char* s, char** end_ptr, locale_t) {
+  return strtof(s, end_ptr);
+}
+
+long strtol_l(const char* s, char** end_ptr, int base, locale_t) {
+  return strtol(s, end_ptr, base);
+}
+
+long double strtold_l(const char* s, char** end_ptr, locale_t) {
+  return strtold(s, end_ptr);
+}
+
+long long strtoll_l(const char* s, char** end_ptr, int base, locale_t) {
+  return strtoll(s, end_ptr, base);
+}
+
+unsigned long strtoul_l(const char* s, char** end_ptr, int base, locale_t) {
+  return strtoul(s, end_ptr, base);
+}
+
+unsigned long long strtoull_l(const char* s, char** end_ptr, int base, locale_t) {
+  return strtoull(s, end_ptr, base);
+}
+
diff --git a/libc/bionic/string_l.cpp b/libc/bionic/string_l.cpp
new file mode 100644
index 0000000..66bfb0e
--- /dev/null
+++ b/libc/bionic/string_l.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <xlocale.h>
+
+int strcoll_l(const char* s1, const char* s2, locale_t) {
+  return strcoll(s1, s2);
+}
+
+char* strerror_l(int error, locale_t) {
+  return strerror(error);
+}
+
+size_t strxfrm_l(char* dst, const char* src, size_t n, locale_t) {
+  return strxfrm(dst, src, n);
+}
diff --git a/libc/bionic/strings_l.cpp b/libc/bionic/strings_l.cpp
new file mode 100644
index 0000000..0983ab1
--- /dev/null
+++ b/libc/bionic/strings_l.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <strings.h>
+#include <xlocale.h>
+
+int strcasecmp_l(const char* s1, const char* s2, locale_t) {
+  return strcasecmp(s1, s2);
+}
+
+int strncasecmp_l(const char* s1, const char* s2, size_t n, locale_t) {
+  return strncasecmp(s1, s2, n);
+}
diff --git a/libc/bionic/wchar.cpp b/libc/bionic/wchar.cpp
index 7717e10..36fc2a2 100644
--- a/libc/bionic/wchar.cpp
+++ b/libc/bionic/wchar.cpp
@@ -210,25 +210,3 @@
 size_t wcsrtombs(char* dst, const wchar_t** src, size_t len, mbstate_t* ps) {
   return wcsnrtombs(dst, src, SIZE_MAX, len, ps);
 }
-
-int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t) {
-  return wcscoll(ws1, ws2);
-}
-
-size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, size_t n, locale_t) {
-  return wcsxfrm(dest, src, n);
-}
-
-long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr, int base,
-                    locale_t) {
-  return wcstoll(nptr, endptr, base);
-}
-
-unsigned long long wcstoull_l(const wchar_t *nptr, wchar_t **endptr,
-                              int base, locale_t) {
-  return wcstoull(nptr, endptr, base);
-}
-
-long double wcstold_l(const wchar_t *nptr, wchar_t **endptr, locale_t) {
-  return wcstold(nptr, endptr);
-}
diff --git a/libc/bionic/wchar_l.cpp b/libc/bionic/wchar_l.cpp
new file mode 100644
index 0000000..6c39e8d
--- /dev/null
+++ b/libc/bionic/wchar_l.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <wchar.h>
+#include <xlocale.h>
+
+int wcscasecmp_l(const wchar_t* ws1, const wchar_t* ws2, locale_t) {
+  return wcscasecmp(ws1, ws2);
+}
+
+int wcsncasecmp_l(const wchar_t* ws1, const wchar_t* ws2, size_t n, locale_t) {
+  return wcsncasecmp(ws1, ws2, n);
+}
+
+int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t) {
+  return wcscoll(ws1, ws2);
+}
+
+size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, size_t n, locale_t) {
+  return wcsxfrm(dest, src, n);
+}
+
+long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr, int base,
+                    locale_t) {
+  return wcstoll(nptr, endptr, base);
+}
+
+unsigned long long wcstoull_l(const wchar_t *nptr, wchar_t **endptr,
+                              int base, locale_t) {
+  return wcstoull(nptr, endptr, base);
+}
+
+long double wcstold_l(const wchar_t *nptr, wchar_t **endptr, locale_t) {
+  return wcstold(nptr, endptr);
+}
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 3cd8ad1..24ddd99 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -225,12 +225,12 @@
 // Implemented as static inlines before 21.
 #endif
 
-#if __ANDROID_API__ >= __ANDROID_API_FUTURE__
+#if __ANDROID_API__ >= __ANDROID_API_O__
 double strtod_l(const char*, char**, locale_t) __INTRODUCED_IN(26);
 float strtof_l(const char*, char**, locale_t) __INTRODUCED_IN(26);
 long strtol_l(const char*, char**, int, locale_t) __INTRODUCED_IN(26);
 #else
-// Implemented as static inlines.
+// Implemented as static inlines before 26.
 #endif
 
 __END_DECLS
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index bec860b..9b16da7 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -22,6 +22,11 @@
 #include <sys/cdefs.h>
 #include <stddef.h> // For size_t.
 
+#define __BEGIN_HIDDEN_DECLS _Pragma("GCC visibility push(hidden)")
+#define __END_HIDDEN_DECLS _Pragma("GCC visibility pop")
+
+extern const char* __progname;
+
 /* Redirect internal C library calls to the public function. */
 #define _err err
 #define _errx errx
diff --git a/libc/upstream-openbsd/lib/libc/crypt/arc4random.c b/libc/upstream-openbsd/lib/libc/crypt/arc4random.c
index 64248b6..8a4ecc9 100644
--- a/libc/upstream-openbsd/lib/libc/crypt/arc4random.c
+++ b/libc/upstream-openbsd/lib/libc/crypt/arc4random.c
@@ -1,9 +1,10 @@
-/*	$OpenBSD: arc4random.c,v 1.50 2014/07/21 18:13:12 deraadt Exp $	*/
+/*	$OpenBSD: arc4random.c,v 1.54 2015/09/13 08:31:47 guenther Exp $	*/
 
 /*
  * Copyright (c) 1996, David Mazieres <dm@uun.org>
  * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
  * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -30,18 +31,18 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/types.h>
-#include <sys/param.h>
 #include <sys/time.h>
 
 #define KEYSTREAM_ONLY
 #include "chacha_private.h"
 
-#define min(a, b) ((a) < (b) ? (a) : (b))
-#ifdef __GNUC__
+#define minimum(a, b) ((a) < (b) ? (a) : (b))
+
+#if defined(__GNUC__) || defined(_MSC_VER)
 #define inline __inline
-#else				/* !__GNUC__ */
+#else				/* __GNUC__ || _MSC_VER */
 #define inline
-#endif				/* !__GNUC__ */
+#endif				/* !__GNUC__ && !_MSC_VER */
 
 #define KEYSZ	32
 #define IVSZ	8
@@ -127,7 +128,7 @@
 	if (dat) {
 		size_t i, m;
 
-		m = min(datlen, KEYSZ + IVSZ);
+		m = minimum(datlen, KEYSZ + IVSZ);
 		for (i = 0; i < m; i++)
 			rsx->rs_buf[i] ^= dat[i];
 	}
@@ -147,7 +148,7 @@
 	_rs_stir_if_needed(n);
 	while (n > 0) {
 		if (rs->rs_have > 0) {
-			m = min(n, rs->rs_have);
+			m = minimum(n, rs->rs_have);
 			keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
 			    - rs->rs_have;
 			memcpy(buf, keystream, m);
@@ -185,6 +186,7 @@
 	_ARC4_UNLOCK();
 	return val;
 }
+DEF_WEAK(arc4random);
 
 void
 arc4random_buf(void *buf, size_t n)
@@ -193,3 +195,4 @@
 	_rs_random_buf(buf, n);
 	_ARC4_UNLOCK();
 }
+DEF_WEAK(arc4random_buf);
diff --git a/libc/upstream-openbsd/lib/libc/crypt/arc4random_uniform.c b/libc/upstream-openbsd/lib/libc/crypt/arc4random_uniform.c
index 1aa9a62..23a15e3 100644
--- a/libc/upstream-openbsd/lib/libc/crypt/arc4random_uniform.c
+++ b/libc/upstream-openbsd/lib/libc/crypt/arc4random_uniform.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: arc4random_uniform.c,v 1.1 2014/07/12 13:24:54 deraadt Exp $	*/
+/*	$OpenBSD: arc4random_uniform.c,v 1.2 2015/09/13 08:31:47 guenther Exp $	*/
 
 /*
  * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
@@ -54,3 +54,4 @@
 
 	return r % upper_bound;
 }
+DEF_WEAK(arc4random_uniform);
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/dmisc.c b/libc/upstream-openbsd/lib/libc/gdtoa/dmisc.c
index a5795cf..f3d8ea7 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/dmisc.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/dmisc.c
@@ -104,6 +104,7 @@
 		dtoa_result = 0;
 #endif
 	}
+DEF_STRONG(freedtoa);
 
  int
 quorem
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/dtoa.c b/libc/upstream-openbsd/lib/libc/gdtoa/dtoa.c
index 668f7b5..c1c8724 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/dtoa.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/dtoa.c
@@ -837,3 +837,4 @@
 		*rve = s;
 	return s0;
 	}
+DEF_STRONG(dtoa);
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoa.c b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoa.c
index fd11de5..feae5af 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoa.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoa.c
@@ -827,3 +827,4 @@
 	*kindp |= inex;
 	return s0;
 	}
+DEF_STRONG(gdtoa);
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
index 7a36967..0f3de12 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
@@ -590,7 +590,7 @@
 			int *decpt, int *sign, char **rve));
  extern char *g__fmt ANSI((char*, char*, char*, int, ULong, size_t));
  extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int));
- extern void hexdig_init_D2A(Void);
+ extern void __hexdig_init_D2A(Void);
  extern int hexnan ANSI((CONST char**, FPI*, ULong*));
  extern int hi0bits_D2A ANSI((ULong));
  extern Bigint *i2b ANSI((int));
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/gethex.c b/libc/upstream-openbsd/lib/libc/gdtoa/gethex.c
index 7ace0fa..f521f15 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/gethex.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/gethex.c
@@ -67,7 +67,7 @@
 #endif
 
 	if (!hexdig['0'])
-		hexdig_init_D2A();
+		__hexdig_init_D2A();
 	*bp = 0;
 	havedig = 0;
 	s0 = *(CONST unsigned char **)sp + 2;
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/hd_init.c b/libc/upstream-openbsd/lib/libc/gdtoa/hd_init.c
index fa6e18d..2227640 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/hd_init.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/hd_init.c
@@ -46,7 +46,7 @@
 	}
 
  void
-hexdig_init_D2A(Void)
+__hexdig_init_D2A(Void)
 {
 #define USC (unsigned char *)
 	htinit(hexdig, USC "0123456789", 0x10);
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/hdtoa.c b/libc/upstream-openbsd/lib/libc/gdtoa/hdtoa.c
index c62f6d5..45caef4 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/hdtoa.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/hdtoa.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: hdtoa.c,v 1.2 2009/10/16 12:15:03 martynas Exp $	*/
+/*	$OpenBSD: hdtoa.c,v 1.3 2015/09/14 12:49:33 guenther Exp $	*/
 /*-
  * Copyright (c) 2004, 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
@@ -210,6 +210,7 @@
 
 	return (s0);
 }
+DEF_STRONG(__hdtoa);
 
 #if (LDBL_MANT_DIG > DBL_MANT_DIG)
 
@@ -319,6 +320,7 @@
 
 	return (s0);
 }
+DEF_STRONG(__hldtoa);
 
 #else	/* (LDBL_MANT_DIG == DBL_MANT_DIG) */
 
@@ -328,5 +330,6 @@
 {
 	return (__hdtoa((double)e, xdigs, ndigits, decpt, sign, rve));
 }
+DEF_STRONG(__hldtoa);
 
 #endif	/* (LDBL_MANT_DIG == DBL_MANT_DIG) */
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/hexnan.c b/libc/upstream-openbsd/lib/libc/gdtoa/hexnan.c
index a443721..b47d499 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/hexnan.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/hexnan.c
@@ -62,7 +62,7 @@
 	int havedig, hd0, i, nbits;
 
 	if (!hexdig['0'])
-		hexdig_init_D2A();
+		__hexdig_init_D2A();
 	nbits = fpi->nbits;
 	x = x0 + (nbits >> kshift);
 	if (nbits & kmask)
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/ldtoa.c b/libc/upstream-openbsd/lib/libc/gdtoa/ldtoa.c
index 16f6f9c..7282e7a 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/ldtoa.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/ldtoa.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ldtoa.c,v 1.2 2014/08/10 02:15:18 guenther Exp $	*/
+/*	$OpenBSD: ldtoa.c,v 1.4 2016/03/09 16:28:47 deraadt Exp $	*/
 /*-
  * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
@@ -26,9 +26,7 @@
  */
 
 #include <sys/types.h>
-#ifndef __vax__
 #include <machine/ieee.h>
-#endif /* !__vax__ */
 #include <float.h>
 #include <stdint.h>
 #include <limits.h>
@@ -106,6 +104,7 @@
 		*decpt = INT_MAX;
 	return ret;
 }
+DEF_STRONG(__ldtoa);
 
 #else   /* (LDBL_MANT_DIG == DBL_MANT_DIG) */
 
@@ -120,5 +119,6 @@
 		*decpt = INT_MAX;
 	return ret;
 }
+DEF_STRONG(__ldtoa);
 
 #endif  /* (LDBL_MANT_DIG == DBL_MANT_DIG) */
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/misc.c b/libc/upstream-openbsd/lib/libc/gdtoa/misc.c
index 6ad706b..b149f07 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/misc.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/misc.c
@@ -98,9 +98,9 @@
 	if (v) {
 		if (v->k > Kmax)
 #ifdef FREE
-			FREE((void*)v);
+			FREE(v);
 #else
-			free((void*)v);
+			free(v);
 #endif
 		else {
 			ACQUIRE_DTOA_LOCK(0);
@@ -876,6 +876,8 @@
 #endif
 		};
 
+#ifdef NO_STRING_H
+
  char *
 #ifdef KR_headers
 strcp_D2A(a, b) char *a; char *b;
@@ -888,8 +890,6 @@
 	return a;
 	}
 
-#ifdef NO_STRING_H
-
  Char *
 #ifdef KR_headers
 memcpy_D2A(a, b, len) Char *a; Char *b; size_t len;
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/strtod.c b/libc/upstream-openbsd/lib/libc/gdtoa/strtod.c
index ded47d8..ac2283c 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/strtod.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/strtod.c
@@ -1102,4 +1102,4 @@
 		*se = (char *)s;
 	return sign ? -dval(&rv) : dval(&rv);
 	}
-
+DEF_STRONG(strtod);
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/strtof.c b/libc/upstream-openbsd/lib/libc/gdtoa/strtof.c
index 224491b..914e218 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/strtof.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/strtof.c
@@ -79,3 +79,4 @@
 		u.L[0] |= 0x80000000L;
 	return u.f;
 	}
+DEF_STRONG(strtof);
diff --git a/libc/upstream-openbsd/lib/libc/gen/alarm.c b/libc/upstream-openbsd/lib/libc/gen/alarm.c
index 2af847a..8bca23a 100644
--- a/libc/upstream-openbsd/lib/libc/gen/alarm.c
+++ b/libc/upstream-openbsd/lib/libc/gen/alarm.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: alarm.c,v 1.7 2005/08/08 08:05:33 espie Exp $ */
+/*	$OpenBSD: alarm.c,v 1.8 2016/01/28 16:40:54 schwarze Exp $ */
 /*
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -28,9 +28,6 @@
  * SUCH DAMAGE.
  */
 
-/*
- * Backwards compatible alarm.
- */
 #include <sys/time.h>
 #include <unistd.h>
 
diff --git a/libc/upstream-openbsd/lib/libc/gen/ctype_.c b/libc/upstream-openbsd/lib/libc/gen/ctype_.c
index 89c8257..8972244 100644
--- a/libc/upstream-openbsd/lib/libc/gen/ctype_.c
+++ b/libc/upstream-openbsd/lib/libc/gen/ctype_.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ctype_.c,v 1.10 2011/09/22 09:06:10 stsp Exp $ */
+/*	$OpenBSD: ctype_.c,v 1.12 2015/09/19 04:02:21 guenther Exp $ */
 /*
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
@@ -74,3 +74,6 @@
 };
 
 const char *_ctype_ = _C_ctype_;
+#if 0
+DEF_STRONG(_ctype_);
+#endif
diff --git a/libc/upstream-openbsd/lib/libc/gen/ftok.c b/libc/upstream-openbsd/lib/libc/gen/ftok.c
index f9d6621..387b80f 100644
--- a/libc/upstream-openbsd/lib/libc/gen/ftok.c
+++ b/libc/upstream-openbsd/lib/libc/gen/ftok.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ftok.c,v 1.7 2005/08/08 08:05:34 espie Exp $ */
+/*	$OpenBSD: ftok.c,v 1.8 2014/11/15 22:38:47 guenther Exp $ */
 /*
  * Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
  * All rights reserved.
@@ -26,7 +26,6 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/ipc.h>
 
diff --git a/libc/upstream-openbsd/lib/libc/gen/getprogname.c b/libc/upstream-openbsd/lib/libc/gen/getprogname.c
index 17046ab..a020830 100644
--- a/libc/upstream-openbsd/lib/libc/gen/getprogname.c
+++ b/libc/upstream-openbsd/lib/libc/gen/getprogname.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getprogname.c,v 1.3 2013/11/12 06:09:48 deraadt Exp $ */
+/* $OpenBSD: getprogname.c,v 1.4 2016/03/13 18:34:20 guenther Exp $ */
 /*
  * Copyright (c) 2013 Antoine Jacoutot <ajacoutot@openbsd.org>
  *
@@ -17,8 +17,6 @@
 
 #include <stdlib.h>
 
-extern const char *__progname;
-
 const char *
 getprogname(void)
 {
diff --git a/libc/upstream-openbsd/lib/libc/gen/isctype.c b/libc/upstream-openbsd/lib/libc/gen/isctype.c
index 970b5e2..a4e944c 100644
--- a/libc/upstream-openbsd/lib/libc/gen/isctype.c
+++ b/libc/upstream-openbsd/lib/libc/gen/isctype.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: isctype.c,v 1.11 2005/08/08 08:05:34 espie Exp $ */
+/*	$OpenBSD: isctype.c,v 1.12 2015/09/13 11:38:08 guenther Exp $ */
 /*
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
@@ -43,6 +43,7 @@
 {
 	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_U|_L|_N)));
 }
+DEF_STRONG(isalnum);
 
 #undef isalpha
 int
@@ -50,6 +51,7 @@
 {
 	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_U|_L)));
 }
+DEF_STRONG(isalpha);
 
 #undef isblank
 int
@@ -57,6 +59,7 @@
 {
 	return (c == ' ' || c == '\t');
 }
+DEF_STRONG(isblank);
 
 #undef iscntrl
 int
@@ -64,6 +67,7 @@
 {
 	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _C));
 }
+DEF_STRONG(iscntrl);
 
 #undef isdigit
 int
@@ -71,6 +75,7 @@
 {
 	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _N));
 }
+DEF_STRONG(isdigit);
 
 #undef isgraph
 int
@@ -78,6 +83,7 @@
 {
 	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_P|_U|_L|_N)));
 }
+DEF_STRONG(isgraph);
 
 #undef islower
 int
@@ -85,6 +91,7 @@
 {
 	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _L));
 }
+DEF_STRONG(islower);
 
 #undef isprint
 int
@@ -92,6 +99,7 @@
 {
 	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_P|_U|_L|_N|_B)));
 }
+DEF_STRONG(isprint);
 
 #undef ispunct
 int
@@ -99,6 +107,7 @@
 {
 	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _P));
 }
+DEF_STRONG(ispunct);
 
 #undef isspace
 int
@@ -106,6 +115,7 @@
 {
 	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _S));
 }
+DEF_STRONG(isspace);
 
 #undef isupper
 int
@@ -113,6 +123,7 @@
 {
 	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _U));
 }
+DEF_STRONG(isupper);
 
 #undef isxdigit
 int
@@ -120,6 +131,7 @@
 {
 	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_N|_X)));
 }
+DEF_STRONG(isxdigit);
 
 #undef isascii
 int
@@ -127,6 +139,7 @@
 {
 	return ((unsigned int)c <= 0177);
 }
+DEF_WEAK(isascii);
 
 #undef toascii
 int
diff --git a/libc/upstream-openbsd/lib/libc/gen/setprogname.c b/libc/upstream-openbsd/lib/libc/gen/setprogname.c
index 089a15a..ec3189f 100644
--- a/libc/upstream-openbsd/lib/libc/gen/setprogname.c
+++ b/libc/upstream-openbsd/lib/libc/gen/setprogname.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: setprogname.c,v 1.4 2013/11/12 06:09:48 deraadt Exp $ */
+/* $OpenBSD: setprogname.c,v 1.5 2016/03/13 18:34:20 guenther Exp $ */
 /*
  * Copyright (c) 2013 Antoine Jacoutot <ajacoutot@openbsd.org>
  *
@@ -18,8 +18,6 @@
 #include <string.h>
 #include <stdlib.h>
 
-extern const char *__progname;
-
 void
 setprogname(const char *progname)
 {
diff --git a/libc/upstream-openbsd/lib/libc/gen/tolower_.c b/libc/upstream-openbsd/lib/libc/gen/tolower_.c
index 50dcc7b..2402c42 100644
--- a/libc/upstream-openbsd/lib/libc/gen/tolower_.c
+++ b/libc/upstream-openbsd/lib/libc/gen/tolower_.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: tolower_.c,v 1.9 2005/08/08 08:05:34 espie Exp $ */
+/*	$OpenBSD: tolower_.c,v 1.11 2015/09/19 04:02:21 guenther Exp $ */
 /*
  * Written by J.T. Conklin <jtc@netbsd.org>.
  * Public domain.
@@ -46,6 +46,9 @@
 };
 
 const short *_tolower_tab_ = _C_tolower_;
+#if 0
+DEF_STRONG(_tolower_tab_);
+#endif
 
 #undef tolower
 int
@@ -55,3 +58,4 @@
 		return(c);
 	return((_tolower_tab_ + 1)[c]);
 }
+DEF_STRONG(tolower);
diff --git a/libc/upstream-openbsd/lib/libc/gen/toupper_.c b/libc/upstream-openbsd/lib/libc/gen/toupper_.c
index 4093199..8408f9e 100644
--- a/libc/upstream-openbsd/lib/libc/gen/toupper_.c
+++ b/libc/upstream-openbsd/lib/libc/gen/toupper_.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: toupper_.c,v 1.10 2005/08/09 08:36:48 kevlo Exp $ */
+/*	$OpenBSD: toupper_.c,v 1.12 2015/09/19 04:02:21 guenther Exp $ */
 /*
  * Written by J.T. Conklin <jtc@netbsd.org>.
  * Public domain.
@@ -47,6 +47,9 @@
 };
 
 const short *_toupper_tab_ = _C_toupper_;
+#if 0
+DEF_STRONG(_toupper_tab_);
+#endif
 
 #undef toupper
 int
@@ -56,3 +59,4 @@
 		return(c);
 	return((_toupper_tab_ + 1)[c]);
 }
+DEF_STRONG(toupper);
diff --git a/libc/upstream-openbsd/lib/libc/gen/verr.c b/libc/upstream-openbsd/lib/libc/gen/verr.c
index 8f4722b..b27b9ca 100644
--- a/libc/upstream-openbsd/lib/libc/gen/verr.c
+++ b/libc/upstream-openbsd/lib/libc/gen/verr.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: verr.c,v 1.10 2015/08/31 02:53:57 guenther Exp $ */
+/*	$OpenBSD: verr.c,v 1.11 2016/03/13 18:34:20 guenther Exp $ */
 /*-
  * Copyright (c) 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -35,8 +35,6 @@
 #include <string.h>
 #include <stdarg.h>
 
-extern char *__progname;		/* Program name, from crt0. */
-
 __dead void
 verr(int eval, const char *fmt, va_list ap)
 {
diff --git a/libc/upstream-openbsd/lib/libc/gen/verrx.c b/libc/upstream-openbsd/lib/libc/gen/verrx.c
index f0186b6..0c9308f 100644
--- a/libc/upstream-openbsd/lib/libc/gen/verrx.c
+++ b/libc/upstream-openbsd/lib/libc/gen/verrx.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: verrx.c,v 1.10 2015/08/31 02:53:57 guenther Exp $ */
+/*	$OpenBSD: verrx.c,v 1.11 2016/03/13 18:34:20 guenther Exp $ */
 /*-
  * Copyright (c) 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -33,8 +33,6 @@
 #include <stdlib.h>
 #include <stdarg.h>
 
-extern char *__progname;		/* Program name, from crt0. */
-
 __dead void
 verrx(int eval, const char *fmt, va_list ap)
 {
diff --git a/libc/upstream-openbsd/lib/libc/gen/vwarn.c b/libc/upstream-openbsd/lib/libc/gen/vwarn.c
index 44d8be4..457d619 100644
--- a/libc/upstream-openbsd/lib/libc/gen/vwarn.c
+++ b/libc/upstream-openbsd/lib/libc/gen/vwarn.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vwarn.c,v 1.10 2015/08/31 02:53:57 guenther Exp $ */
+/*	$OpenBSD: vwarn.c,v 1.11 2016/03/13 18:34:20 guenther Exp $ */
 /*-
  * Copyright (c) 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,11 +31,10 @@
 #include <err.h>
 #include <errno.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
 
-extern char *__progname;		/* Program name, from crt0. */
-
 void
 vwarn(const char *fmt, va_list ap)
 {
diff --git a/libc/upstream-openbsd/lib/libc/gen/vwarnx.c b/libc/upstream-openbsd/lib/libc/gen/vwarnx.c
index 67d8f5b..146e267 100644
--- a/libc/upstream-openbsd/lib/libc/gen/vwarnx.c
+++ b/libc/upstream-openbsd/lib/libc/gen/vwarnx.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vwarnx.c,v 1.10 2015/08/31 02:53:57 guenther Exp $ */
+/*	$OpenBSD: vwarnx.c,v 1.11 2016/03/13 18:34:20 guenther Exp $ */
 /*-
  * Copyright (c) 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -30,10 +30,9 @@
 
 #include <err.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <stdarg.h>
 
-extern char *__progname;		/* Program name, from crt0. */
-
 void
 vwarnx(const char *fmt, va_list ap)
 {
diff --git a/libc/upstream-openbsd/lib/libc/include/ctype_private.h b/libc/upstream-openbsd/lib/libc/include/ctype_private.h
index 39cc792..cbe1b20 100644
--- a/libc/upstream-openbsd/lib/libc/include/ctype_private.h
+++ b/libc/upstream-openbsd/lib/libc/include/ctype_private.h
@@ -1,7 +1,9 @@
-/* $OpenBSD: ctype_private.h,v 1.1 2005/08/08 05:53:00 espie Exp $ */
+/* $OpenBSD: ctype_private.h,v 1.2 2015/08/27 04:37:09 guenther Exp $ */
 /* Written by Marc Espie, public domain */
 #define CTYPE_NUM_CHARS       256
+
+__BEGIN_HIDDEN_DECLS
 extern const char _C_ctype_[];
 extern const short _C_toupper_[];
 extern const short _C_tolower_[];
-
+__END_HIDDEN_DECLS
diff --git a/libc/upstream-openbsd/lib/libc/locale/_wcstol.h b/libc/upstream-openbsd/lib/libc/locale/_wcstol.h
index 7b49bbf..1b60a3a 100644
--- a/libc/upstream-openbsd/lib/libc/locale/_wcstol.h
+++ b/libc/upstream-openbsd/lib/libc/locale/_wcstol.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: _wcstol.h,v 1.1 2005/07/01 08:59:27 espie Exp $	*/
+/*	$OpenBSD: _wcstol.h,v 1.3 2015/10/01 02:32:07 guenther Exp $	*/
 /* $NetBSD: _wcstol.h,v 1.2 2003/08/07 16:43:03 agc Exp $ */
 
 /*-
@@ -130,7 +130,7 @@
 		}
 	}
 	if (endptr != 0)
-		/* LINTED interface specification */
 		*endptr = (wchar_t *)(any ? s - 1 : nptr);
 	return (acc);
 }
+DEF_STRONG(FUNCNAME);
diff --git a/libc/upstream-openbsd/lib/libc/locale/_wcstoul.h b/libc/upstream-openbsd/lib/libc/locale/_wcstoul.h
index 736b38f..159b22b 100644
--- a/libc/upstream-openbsd/lib/libc/locale/_wcstoul.h
+++ b/libc/upstream-openbsd/lib/libc/locale/_wcstoul.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: _wcstoul.h,v 1.1 2005/07/01 08:59:27 espie Exp $	*/
+/*	$OpenBSD: _wcstoul.h,v 1.3 2015/10/01 02:32:07 guenther Exp $	*/
 /* $NetBSD: _wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp $ */
 
 /*
@@ -110,7 +110,7 @@
 	if (neg && any > 0)
 		acc = -acc;
 	if (endptr != 0)
-		/* LINTED interface specification */
 		*endptr = (wchar_t *)(any ? s - 1 : nptr);
 	return (acc);
 }
+DEF_STRONG(FUNCNAME);
diff --git a/libc/upstream-openbsd/lib/libc/locale/btowc.c b/libc/upstream-openbsd/lib/libc/locale/btowc.c
index 9627340..455b346 100644
--- a/libc/upstream-openbsd/lib/libc/locale/btowc.c
+++ b/libc/upstream-openbsd/lib/libc/locale/btowc.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: btowc.c,v 1.2 2012/12/05 23:20:00 deraadt Exp $ */
+/*	$OpenBSD: btowc.c,v 1.3 2015/09/12 16:23:14 guenther Exp $ */
 
 /*-
  * Copyright (c) 2002, 2003 Tim J. Robbins.
@@ -50,3 +50,4 @@
 		return (WEOF);
 	return (wc);
 }
+DEF_STRONG(btowc);
diff --git a/libc/upstream-openbsd/lib/libc/locale/mbrlen.c b/libc/upstream-openbsd/lib/libc/locale/mbrlen.c
index 0f05bd0..52df61a 100644
--- a/libc/upstream-openbsd/lib/libc/locale/mbrlen.c
+++ b/libc/upstream-openbsd/lib/libc/locale/mbrlen.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: mbrlen.c,v 1.2 2012/12/05 23:20:00 deraadt Exp $ */
+/*	$OpenBSD: mbrlen.c,v 1.3 2015/09/12 16:23:14 guenther Exp $ */
 
 /*-
  * Copyright (c) 2002-2004 Tim J. Robbins.
@@ -37,3 +37,4 @@
 		ps = &mbs;
 	return (mbrtowc(NULL, s, n, ps));
 }
+DEF_STRONG(mbrlen);
diff --git a/libc/upstream-openbsd/lib/libc/locale/wctob.c b/libc/upstream-openbsd/lib/libc/locale/wctob.c
index ea1f40c..51ac355 100644
--- a/libc/upstream-openbsd/lib/libc/locale/wctob.c
+++ b/libc/upstream-openbsd/lib/libc/locale/wctob.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: wctob.c,v 1.2 2012/12/05 23:20:00 deraadt Exp $ */
+/*	$OpenBSD: wctob.c,v 1.3 2015/09/12 16:23:14 guenther Exp $ */
 /*-
  * Copyright (c) 2002-2004 Tim J. Robbins.
  * All rights reserved.
@@ -41,3 +41,4 @@
 		return (EOF);
 	return ((unsigned char)*buf);
 }
+DEF_STRONG(wctob);
diff --git a/libc/upstream-openbsd/lib/libc/locale/wctoint.h b/libc/upstream-openbsd/lib/libc/locale/wctoint.h
index c9bf084..ea50c5a 100644
--- a/libc/upstream-openbsd/lib/libc/locale/wctoint.h
+++ b/libc/upstream-openbsd/lib/libc/locale/wctoint.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: wctoint.h,v 1.1 2005/07/01 08:59:27 espie Exp $	*/
+/*	$OpenBSD: wctoint.h,v 1.2 2015/09/13 11:38:08 guenther Exp $	*/
 /* $NetBSD: __wctoint.h,v 1.1 2001/09/28 11:25:37 yamt Exp $ */
 
 /*-
@@ -30,7 +30,7 @@
  */
 
 
-__inline static int
+inline static int
 wctoint(wchar_t wc)
 {
 	int n;
diff --git a/libc/upstream-openbsd/lib/libc/net/inet_lnaof.c b/libc/upstream-openbsd/lib/libc/net/inet_lnaof.c
index b1a58cd..9284538 100644
--- a/libc/upstream-openbsd/lib/libc/net/inet_lnaof.c
+++ b/libc/upstream-openbsd/lib/libc/net/inet_lnaof.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: inet_lnaof.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
+/*	$OpenBSD: inet_lnaof.c,v 1.7 2015/01/16 16:48:51 deraadt Exp $ */
 /*
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -28,7 +28,6 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/param.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
diff --git a/libc/upstream-openbsd/lib/libc/net/inet_makeaddr.c b/libc/upstream-openbsd/lib/libc/net/inet_makeaddr.c
index 87d9325..88ddd28 100644
--- a/libc/upstream-openbsd/lib/libc/net/inet_makeaddr.c
+++ b/libc/upstream-openbsd/lib/libc/net/inet_makeaddr.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: inet_makeaddr.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
+/*	$OpenBSD: inet_makeaddr.c,v 1.7 2015/01/16 16:48:51 deraadt Exp $ */
 /*
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -28,7 +28,6 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/param.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
diff --git a/libc/upstream-openbsd/lib/libc/net/inet_netof.c b/libc/upstream-openbsd/lib/libc/net/inet_netof.c
index 2f468c3..4efceed 100644
--- a/libc/upstream-openbsd/lib/libc/net/inet_netof.c
+++ b/libc/upstream-openbsd/lib/libc/net/inet_netof.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: inet_netof.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
+/*	$OpenBSD: inet_netof.c,v 1.7 2015/01/16 16:48:51 deraadt Exp $ */
 /*
  * Copyright (c) 1983, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -28,7 +28,6 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/param.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
diff --git a/libc/upstream-openbsd/lib/libc/net/inet_ntop.c b/libc/upstream-openbsd/lib/libc/net/inet_ntop.c
index f991a07..2bb11c2 100644
--- a/libc/upstream-openbsd/lib/libc/net/inet_ntop.c
+++ b/libc/upstream-openbsd/lib/libc/net/inet_ntop.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: inet_ntop.c,v 1.10 2014/05/17 18:16:14 tedu Exp $	*/
+/*	$OpenBSD: inet_ntop.c,v 1.13 2016/09/21 04:38:56 guenther Exp $	*/
 
 /* Copyright (c) 1996 by Internet Software Consortium.
  *
@@ -16,7 +16,6 @@
  * SOFTWARE.
  */
 
-#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -47,15 +46,16 @@
 {
 	switch (af) {
 	case AF_INET:
-		return (inet_ntop4(src, dst, (size_t)size));
+		return (inet_ntop4(src, dst, size));
 	case AF_INET6:
-		return (inet_ntop6(src, dst, (size_t)size));
+		return (inet_ntop6(src, dst, size));
 	default:
 		errno = EAFNOSUPPORT;
 		return (NULL);
 	}
 	/* NOTREACHED */
 }
+DEF_WEAK(inet_ntop);
 
 /* const char *
  * inet_ntop4(src, dst, size)
@@ -167,7 +167,7 @@
 		/* Is this address an encapsulated IPv4? */
 		if (i == 6 && best.base == 0 &&
 		    (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
-			if (!inet_ntop4(src+12, tp, (size_t)(ep - tp)))
+			if (!inet_ntop4(src+12, tp, ep - tp))
 				return (NULL);
 			tp += strlen(tp);
 			break;
diff --git a/libc/upstream-openbsd/lib/libc/net/inet_pton.c b/libc/upstream-openbsd/lib/libc/net/inet_pton.c
index 7e521c3..5d7148e 100644
--- a/libc/upstream-openbsd/lib/libc/net/inet_pton.c
+++ b/libc/upstream-openbsd/lib/libc/net/inet_pton.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: inet_pton.c,v 1.8 2010/05/06 15:47:14 claudio Exp $	*/
+/*	$OpenBSD: inet_pton.c,v 1.10 2015/09/13 21:36:08 guenther Exp $	*/
 
 /* Copyright (c) 1996 by Internet Software Consortium.
  *
@@ -16,7 +16,6 @@
  * SOFTWARE.
  */
 
-#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -58,6 +57,7 @@
 	}
 	/* NOTREACHED */
 }
+DEF_WEAK(inet_pton);
 
 /* int
  * inet_pton4(src, dst)
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fflush.c b/libc/upstream-openbsd/lib/libc/stdio/fflush.c
index 3e30f10..fd1a4b3 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fflush.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fflush.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fflush.c,v 1.8 2009/11/09 00:18:27 kurt Exp $ */
+/*	$OpenBSD: fflush.c,v 1.9 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -52,6 +52,7 @@
 	FUNLOCKFILE(fp);
 	return (r);
 }
+DEF_STRONG(fflush);
 
 int
 __sflush(FILE *fp)
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fgets.c b/libc/upstream-openbsd/lib/libc/stdio/fgets.c
index 345884a..3cea8f7 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fgets.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fgets.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fgets.c,v 1.14 2009/11/09 00:18:27 kurt Exp $ */
+/*	$OpenBSD: fgets.c,v 1.16 2016/09/21 04:38:56 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -83,19 +83,19 @@
 		 */
 		if (len > n)
 			len = n;
-		t = memchr((void *)p, '\n', len);
+		t = memchr(p, '\n', len);
 		if (t != NULL) {
 			len = ++t - p;
 			fp->_r -= len;
 			fp->_p = t;
-			(void)memcpy((void *)s, (void *)p, len);
+			(void)memcpy(s, p, len);
 			s[len] = '\0';
 			FUNLOCKFILE(fp);
 			return (buf);
 		}
 		fp->_r -= len;
 		fp->_p += len;
-		(void)memcpy((void *)s, (void *)p, len);
+		(void)memcpy(s, p, len);
 		s += len;
 		n -= len;
 	}
@@ -103,3 +103,4 @@
 	FUNLOCKFILE(fp);
 	return (buf);
 }
+DEF_STRONG(fgets);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fmemopen.c b/libc/upstream-openbsd/lib/libc/stdio/fmemopen.c
index 8cda047..00c2764 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fmemopen.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fmemopen.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fmemopen.c,v 1.2 2013/03/27 15:06:25 mpi Exp $	*/
+/*	$OpenBSD: fmemopen.c,v 1.3 2015/08/31 02:53:57 guenther Exp $	*/
 
 /*
  * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
@@ -181,3 +181,4 @@
 
 	return (fp);
 }
+DEF_WEAK(fmemopen);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fpurge.c b/libc/upstream-openbsd/lib/libc/stdio/fpurge.c
index 65bd749..8dd8a91 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fpurge.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fpurge.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fpurge.c,v 1.9 2009/11/09 00:18:27 kurt Exp $ */
+/*	$OpenBSD: fpurge.c,v 1.10 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -59,3 +59,4 @@
 	FUNLOCKFILE(fp);
 	return (0);
 }
+DEF_WEAK(fpurge);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fputs.c b/libc/upstream-openbsd/lib/libc/stdio/fputs.c
index ea8556a..05ead5c 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fputs.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fputs.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fputs.c,v 1.10 2009/11/09 00:18:27 kurt Exp $ */
+/*	$OpenBSD: fputs.c,v 1.11 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -56,3 +56,4 @@
 	FUNLOCKFILE(fp);
 	return (ret);
 }
+DEF_STRONG(fputs);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fputws.c b/libc/upstream-openbsd/lib/libc/stdio/fputws.c
index 108846e..8961571 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fputws.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fputws.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fputws.c,v 1.7 2013/11/12 07:04:35 deraadt Exp $	*/
+/*	$OpenBSD: fputws.c,v 1.8 2015/08/31 02:53:57 guenther Exp $	*/
 /* $NetBSD: fputws.c,v 1.1 2003/03/07 07:11:37 tshiozak Exp $ */
 
 /*-
@@ -55,3 +55,4 @@
 
 	return (0);
 }
+DEF_STRONG(fputws);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fvwrite.h b/libc/upstream-openbsd/lib/libc/stdio/fvwrite.h
index d3a309b..f04565b 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fvwrite.h
+++ b/libc/upstream-openbsd/lib/libc/stdio/fvwrite.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fvwrite.h,v 1.6 2013/11/12 07:04:35 deraadt Exp $	*/
+/*	$OpenBSD: fvwrite.h,v 1.7 2015/08/27 04:37:09 guenther Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993
@@ -45,5 +45,7 @@
 	int	uio_resid;
 };
 
+__BEGIN_HIDDEN_DECLS
 extern int __sfvwrite(FILE *, struct __suio *);
 wint_t __fputwc_unlock(wchar_t wc, FILE *fp);
+__END_HIDDEN_DECLS
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fwalk.c b/libc/upstream-openbsd/lib/libc/stdio/fwalk.c
index 8ac6628..4b1aa43 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fwalk.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fwalk.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fwalk.c,v 1.10 2009/11/09 00:18:27 kurt Exp $ */
+/*	$OpenBSD: fwalk.c,v 1.12 2016/05/23 00:21:48 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fwide.c b/libc/upstream-openbsd/lib/libc/stdio/fwide.c
index 93cddc6..27ca0f8 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fwide.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fwide.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fwide.c,v 1.4 2009/11/09 00:18:27 kurt Exp $	*/
+/*	$OpenBSD: fwide.c,v 1.5 2015/08/31 02:53:57 guenther Exp $	*/
 /* $NetBSD: fwide.c,v 1.2 2003/01/18 11:29:54 thorpej Exp $ */
 
 /*-
@@ -62,3 +62,4 @@
 
 	return mode;
 }
+DEF_STRONG(fwide);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fwrite.c b/libc/upstream-openbsd/lib/libc/stdio/fwrite.c
index c72d968..f829398 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fwrite.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fwrite.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fwrite.c,v 1.11 2014/05/01 16:40:36 deraadt Exp $ */
+/*	$OpenBSD: fwrite.c,v 1.12 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -86,3 +86,4 @@
 		return (count);
 	return ((n - uio.uio_resid) / size);
 }
+DEF_STRONG(fwrite);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/mktemp.c b/libc/upstream-openbsd/lib/libc/stdio/mktemp.c
index 956608c..4b81d5d 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/mktemp.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/mktemp.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: mktemp.c,v 1.35 2014/10/31 15:54:14 millert Exp $ */
+/*	$OpenBSD: mktemp.c,v 1.38 2015/09/13 08:31:47 guenther Exp $ */
 /*
  * Copyright (c) 1996-1998, 2008 Theo de Raadt
  * Copyright (c) 1997, 2008-2009 Todd C. Miller
@@ -110,8 +110,6 @@
 	return(-1);
 }
 
-char *_mktemp(char *);
-
 char *
 _mktemp(char *path)
 {
@@ -140,12 +138,14 @@
 {
 	return(mktemp_internal(path, 0, MKTEMP_FILE, 0));
 }
+DEF_WEAK(mkstemp);
 
 int
 mkostemp(char *path, int flags)
 {
 	return(mktemp_internal(path, 0, MKTEMP_FILE, flags));
 }
+DEF_WEAK(mkostemp);
 
 int
 mkstemps(char *path, int slen)
diff --git a/libc/upstream-openbsd/lib/libc/stdio/perror.c b/libc/upstream-openbsd/lib/libc/stdio/perror.c
index 8728718..fdd6120 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/perror.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/perror.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: perror.c,v 1.8 2005/08/08 08:05:36 espie Exp $ */
+/*	$OpenBSD: perror.c,v 1.9 2015/08/31 02:53:57 guenther Exp $ */
 /*
  * Copyright (c) 1988, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -60,3 +60,4 @@
 	v->iov_len = 1;
 	(void)writev(STDERR_FILENO, iov, (v - iov) + 1);
 }
+DEF_STRONG(perror);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/puts.c b/libc/upstream-openbsd/lib/libc/stdio/puts.c
index 655aed7..57d4b78 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/puts.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/puts.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: puts.c,v 1.11 2009/11/21 09:53:44 guenther Exp $ */
+/*	$OpenBSD: puts.c,v 1.12 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -60,3 +60,4 @@
 	FUNLOCKFILE(stdout);
 	return (ret ? EOF : '\n');
 }
+DEF_STRONG(puts);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/rget.c b/libc/upstream-openbsd/lib/libc/stdio/rget.c
index 4cd97cb..368815b 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/rget.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/rget.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: rget.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
+/*	$OpenBSD: rget.c,v 1.8 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -49,3 +49,4 @@
 	}
 	return (EOF);
 }
+DEF_STRONG(__srget);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c b/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
index 9b2ab57..da68b90 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: setvbuf.c,v 1.12 2015/01/13 07:18:21 guenther Exp $ */
+/*	$OpenBSD: setvbuf.c,v 1.14 2016/09/21 04:38:56 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -70,7 +70,7 @@
 	fp->_r = fp->_lbfsize = 0;
 	flags = fp->_flags;
 	if (flags & __SMBF)
-		free((void *)fp->_bf._base);
+		free(fp->_bf._base);
 	flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT | __SEOF);
 
 	/* If setting unbuffered mode, skip all the hard work. */
@@ -157,3 +157,4 @@
 
 	return (ret);
 }
+DEF_STRONG(setvbuf);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/tmpnam.c b/libc/upstream-openbsd/lib/libc/stdio/tmpnam.c
index 32e0a22..d6dc10e 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/tmpnam.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/tmpnam.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: tmpnam.c,v 1.10 2005/08/08 08:05:36 espie Exp $ */
+/*	$OpenBSD: tmpnam.c,v 1.11 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993, 1994
  *	The Regents of the University of California.  All rights reserved.
@@ -39,8 +39,6 @@
 __warn_references(tmpnam,
     "warning: tmpnam() possibly used unsafely; consider using mkstemp()");
 
-extern char *_mktemp(char *);
-
 char *
 tmpnam(char *s)
 {
diff --git a/libc/upstream-openbsd/lib/libc/stdio/ungetc.c b/libc/upstream-openbsd/lib/libc/stdio/ungetc.c
index ec98f26..4cd638b 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/ungetc.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/ungetc.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ungetc.c,v 1.13 2014/10/11 04:05:10 deraadt Exp $ */
+/*	$OpenBSD: ungetc.c,v 1.15 2016/09/21 04:38:56 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -53,7 +53,7 @@
 		/*
 		 * Get a new buffer (rather than expanding the old one).
 		 */
-		if ((p = malloc((size_t)BUFSIZ)) == NULL)
+		if ((p = malloc(BUFSIZ)) == NULL)
 			return (EOF);
 		_UB(fp)._base = p;
 		_UB(fp)._size = BUFSIZ;
@@ -68,7 +68,7 @@
 	if (p == NULL)
 		return (EOF);
 	/* no overlap (hence can use memcpy) because we doubled the size */
-	(void)memcpy((void *)(p + i), (void *)p, (size_t)i);
+	(void)memcpy(p + i, p, i);
 	fp->_p = p + i;
 	_UB(fp)._base = p;
 	_UB(fp)._size = i * 2;
@@ -143,3 +143,4 @@
 	FUNLOCKFILE(fp);
 	return (c);
 }
+DEF_STRONG(ungetc);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/ungetwc.c b/libc/upstream-openbsd/lib/libc/stdio/ungetwc.c
index c0321e9..9b312df 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/ungetwc.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/ungetwc.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ungetwc.c,v 1.5 2011/10/16 13:20:51 stsp Exp $	*/
+/*	$OpenBSD: ungetwc.c,v 1.6 2015/08/31 02:53:57 guenther Exp $	*/
 /* $NetBSD: ungetwc.c,v 1.2 2003/01/18 11:29:59 thorpej Exp $ */
 
 /*-
@@ -75,3 +75,4 @@
 	FUNLOCKFILE(fp);
 	return (r);
 }
+DEF_STRONG(ungetwc);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vdprintf.c b/libc/upstream-openbsd/lib/libc/stdio/vdprintf.c
index 49c1969..e76fcd4 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/vdprintf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/vdprintf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vdprintf.c,v 1.1 2013/01/30 00:08:13 brad Exp $	*/
+/*	$OpenBSD: vdprintf.c,v 1.2 2015/08/31 02:53:57 guenther Exp $	*/
 /*	$FreeBSD: src/lib/libc/stdio/vdprintf.c,v 1.4 2012/11/17 01:49:40 svnexp Exp $ */
 
 /*-
@@ -71,3 +71,4 @@
 
 	return fflush(&f) ? EOF : ret;
 }
+DEF_WEAK(vdprintf);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vsscanf.c b/libc/upstream-openbsd/lib/libc/stdio/vsscanf.c
index 71eb752..86e0b4c 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/vsscanf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/vsscanf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vsscanf.c,v 1.12 2011/11/08 18:30:42 guenther Exp $ */
+/*	$OpenBSD: vsscanf.c,v 1.13 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -35,7 +35,6 @@
 #include <string.h>
 #include "local.h"
 
-/* ARGSUSED */
 static int
 eofread(void *cookie, char *buf, int len)
 {
@@ -57,3 +56,4 @@
 	f._lb._base = NULL;
 	return (__svfscanf(&f, fmt, ap));
 }
+DEF_STRONG(vsscanf);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vswscanf.c b/libc/upstream-openbsd/lib/libc/stdio/vswscanf.c
index cbaa250..e87dfeb 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/vswscanf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/vswscanf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vswscanf.c,v 1.2 2012/12/05 23:20:01 deraadt Exp $ */
+/* $OpenBSD: vswscanf.c,v 1.3 2015/08/31 02:53:57 guenther Exp $ */
 
 /*-
  * Copyright (c) 1990, 1993
@@ -86,3 +86,4 @@
 
 	return (r);
 }
+DEF_STRONG(vswscanf);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/wbuf.c b/libc/upstream-openbsd/lib/libc/stdio/wbuf.c
index 6aa00e1..2d07750 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/wbuf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/wbuf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: wbuf.c,v 1.12 2009/11/09 00:18:28 kurt Exp $ */
+/*	$OpenBSD: wbuf.c,v 1.13 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -82,3 +82,4 @@
 			return (EOF);
 	return (c);
 }
+DEF_STRONG(__swbuf);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/abs.c b/libc/upstream-openbsd/lib/libc/stdlib/abs.c
index 5d2fbae..0e39cc5 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/abs.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/abs.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: abs.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
+/*	$OpenBSD: abs.c,v 1.6 2015/09/13 08:31:47 guenther Exp $ */
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
@@ -35,3 +35,4 @@
 {
 	return(j < 0 ? -j : j);
 }
+DEF_STRONG(abs);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/atoi.c b/libc/upstream-openbsd/lib/libc/stdlib/atoi.c
index b084267..7c9eb13 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/atoi.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/atoi.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: atoi.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
+/*	$OpenBSD: atoi.c,v 1.6 2015/09/13 08:31:47 guenther Exp $ */
 /*
  * Copyright (c) 1988 Regents of the University of California.
  * All rights reserved.
@@ -35,3 +35,4 @@
 {
 	return((int)strtol(str, (char **)NULL, 10));
 }
+DEF_STRONG(atoi);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/tfind.c b/libc/upstream-openbsd/lib/libc/stdlib/tfind.c
index 0d1d519..49f9dbc 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/tfind.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/tfind.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: tfind.c,v 1.6 2014/03/16 18:38:30 guenther Exp $	*/
+/*	$OpenBSD: tfind.c,v 1.7 2015/09/26 16:03:48 guenther Exp $	*/
 
 /*
  * Tree search generalized from Knuth (6.2.2) Algorithm T just like
@@ -10,7 +10,6 @@
  *
  * Totally public domain.
  */
-/*LINTLIBRARY*/
 #include <search.h>
 
 typedef struct node_t
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/tsearch.c b/libc/upstream-openbsd/lib/libc/stdlib/tsearch.c
index a141085..1dd3145 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/tsearch.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/tsearch.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: tsearch.c,v 1.8 2014/03/16 18:38:30 guenther Exp $	*/
+/*	$OpenBSD: tsearch.c,v 1.10 2015/09/26 16:03:48 guenther Exp $	*/
 
 /*
  * Tree search generalized from Knuth (6.2.2) Algorithm T just like
@@ -10,7 +10,6 @@
  *
  * Totally public domain.
  */
-/*LINTLIBRARY*/
 
 #include <search.h>
 #include <stdlib.h>
@@ -40,7 +39,7 @@
 	    &(*rootp)->left :		/* T3: follow left branch */
 	    &(*rootp)->right;		/* T4: follow right branch */
     }
-    q = (node *) malloc(sizeof(node));	/* T5: key not found */
+    q = malloc(sizeof(node));	/* T5: key not found */
     if (q != (struct node_t *)0) {	/* make new node */
 	*rootp = q;			/* link new node to old */
 	q->key = key;			/* initialize new node */
diff --git a/libc/upstream-openbsd/lib/libc/string/memchr.c b/libc/upstream-openbsd/lib/libc/string/memchr.c
index 05a1197..976ed21 100644
--- a/libc/upstream-openbsd/lib/libc/string/memchr.c
+++ b/libc/upstream-openbsd/lib/libc/string/memchr.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: memchr.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */
+/*	$OpenBSD: memchr.c,v 1.8 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
@@ -34,7 +34,8 @@
 #include <string.h>
 
 void *
-memchr(const void *s, int c, size_t n) __overloadable {
+memchr(const void *s, int c, size_t n) __overloadable
+{
 	if (n != 0) {
 		const unsigned char *p = s;
 
@@ -45,3 +46,4 @@
 	}
 	return (NULL);
 }
+DEF_STRONG(memchr);
diff --git a/libc/upstream-openbsd/lib/libc/string/memmove.c b/libc/upstream-openbsd/lib/libc/string/memmove.c
index 910f48c..6b5db47 100644
--- a/libc/upstream-openbsd/lib/libc/string/memmove.c
+++ b/libc/upstream-openbsd/lib/libc/string/memmove.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: memmove.c,v 1.1 2014/11/30 19:43:56 deraadt Exp $ */
+/*	$OpenBSD: memmove.c,v 1.2 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
@@ -110,3 +110,4 @@
 done:
 	return (dst0);
 }
+DEF_STRONG(memmove);
diff --git a/libc/upstream-openbsd/lib/libc/string/memrchr.c b/libc/upstream-openbsd/lib/libc/string/memrchr.c
index 1cce809..4b67503 100644
--- a/libc/upstream-openbsd/lib/libc/string/memrchr.c
+++ b/libc/upstream-openbsd/lib/libc/string/memrchr.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: memrchr.c,v 1.2 2007/11/27 16:22:12 martynas Exp $	*/
+/*	$OpenBSD: memrchr.c,v 1.3 2015/08/31 02:53:57 guenther Exp $	*/
 
 /*
  * Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -36,3 +36,4 @@
 	}
 	return(NULL);
 }
+DEF_WEAK(memrchr);
diff --git a/libc/upstream-openbsd/lib/libc/string/stpncpy.c b/libc/upstream-openbsd/lib/libc/string/stpncpy.c
index 661a4fd..f30bf15 100644
--- a/libc/upstream-openbsd/lib/libc/string/stpncpy.c
+++ b/libc/upstream-openbsd/lib/libc/string/stpncpy.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: stpncpy.c,v 1.2 2012/07/11 10:44:59 naddy Exp $	*/
+/*	$OpenBSD: stpncpy.c,v 1.3 2015/08/31 02:53:57 guenther Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -54,3 +54,4 @@
 	}
 	return (dst);
 }
+DEF_WEAK(stpncpy);
diff --git a/libc/upstream-openbsd/lib/libc/string/strcasecmp.c b/libc/upstream-openbsd/lib/libc/string/strcasecmp.c
index 2be0913..edbd638 100644
--- a/libc/upstream-openbsd/lib/libc/string/strcasecmp.c
+++ b/libc/upstream-openbsd/lib/libc/string/strcasecmp.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strcasecmp.c,v 1.6 2005/08/08 08:05:37 espie Exp $	*/
+/*	$OpenBSD: strcasecmp.c,v 1.7 2015/08/31 02:53:57 guenther Exp $	*/
 
 /*
  * Copyright (c) 1987, 1993
@@ -85,6 +85,7 @@
 			return (0);
 	return (cm[*us1] - cm[*--us2]);
 }
+DEF_WEAK(strcasecmp);
 
 int
 strncasecmp(const char *s1, const char *s2, size_t n)
@@ -103,3 +104,4 @@
 	}
 	return (0);
 }
+DEF_WEAK(strncasecmp);
diff --git a/libc/upstream-openbsd/lib/libc/string/strcmp.c b/libc/upstream-openbsd/lib/libc/string/strcmp.c
index d1b6c50..be17556 100644
--- a/libc/upstream-openbsd/lib/libc/string/strcmp.c
+++ b/libc/upstream-openbsd/lib/libc/string/strcmp.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strcmp.c,v 1.8 2014/06/10 04:17:37 deraadt Exp $	*/
+/*	$OpenBSD: strcmp.c,v 1.9 2015/08/31 02:53:57 guenther Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -45,3 +45,4 @@
 			return (0);
 	return (*(unsigned char *)s1 - *(unsigned char *)--s2);
 }
+DEF_STRONG(strcmp);
diff --git a/libc/upstream-openbsd/lib/libc/string/strcspn.c b/libc/upstream-openbsd/lib/libc/string/strcspn.c
index 1eb2336..3c1f5a4 100644
--- a/libc/upstream-openbsd/lib/libc/string/strcspn.c
+++ b/libc/upstream-openbsd/lib/libc/string/strcspn.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strcspn.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
+/*	$OpenBSD: strcspn.c,v 1.6 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
@@ -56,3 +56,4 @@
 	}
 	/* NOTREACHED */
 }
+DEF_STRONG(strcspn);
diff --git a/libc/upstream-openbsd/lib/libc/string/strdup.c b/libc/upstream-openbsd/lib/libc/string/strdup.c
index a6aa1e0..9aebf39 100644
--- a/libc/upstream-openbsd/lib/libc/string/strdup.c
+++ b/libc/upstream-openbsd/lib/libc/string/strdup.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strdup.c,v 1.6 2005/08/08 08:05:37 espie Exp $	*/
+/*	$OpenBSD: strdup.c,v 1.7 2015/08/31 02:53:57 guenther Exp $	*/
 
 /*
  * Copyright (c) 1988, 1993
@@ -47,3 +47,4 @@
 	(void)memcpy(copy, str, siz);
 	return(copy);
 }
+DEF_WEAK(strdup);
diff --git a/libc/upstream-openbsd/lib/libc/string/strlcat.c b/libc/upstream-openbsd/lib/libc/string/strlcat.c
index 7bf98aa..8a950f5 100644
--- a/libc/upstream-openbsd/lib/libc/string/strlcat.c
+++ b/libc/upstream-openbsd/lib/libc/string/strlcat.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strlcat.c,v 1.16 2015/08/31 02:53:57 guenther Exp $	*/
+/*	$OpenBSD: strlcat.c,v 1.18 2016/10/16 17:37:39 dtucker Exp $	*/
 
 /*
  * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
diff --git a/libc/upstream-openbsd/lib/libc/string/strlcpy.c b/libc/upstream-openbsd/lib/libc/string/strlcpy.c
index a5343b8..647b18b 100644
--- a/libc/upstream-openbsd/lib/libc/string/strlcpy.c
+++ b/libc/upstream-openbsd/lib/libc/string/strlcpy.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strlcpy.c,v 1.13 2015/08/31 02:53:57 guenther Exp $	*/
+/*	$OpenBSD: strlcpy.c,v 1.15 2016/10/16 17:37:39 dtucker Exp $	*/
 
 /*
  * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
diff --git a/libc/upstream-openbsd/lib/libc/string/strncat.c b/libc/upstream-openbsd/lib/libc/string/strncat.c
index 32334b3..5b07749 100644
--- a/libc/upstream-openbsd/lib/libc/string/strncat.c
+++ b/libc/upstream-openbsd/lib/libc/string/strncat.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strncat.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
+/*	$OpenBSD: strncat.c,v 1.6 2015/08/31 02:53:57 guenther Exp $ */
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
@@ -55,3 +55,4 @@
 	}
 	return (dst);
 }
+DEF_STRONG(strncat);
diff --git a/libc/upstream-openbsd/lib/libc/string/strncmp.c b/libc/upstream-openbsd/lib/libc/string/strncmp.c
index 0a4ddc1..535d2a6 100644
--- a/libc/upstream-openbsd/lib/libc/string/strncmp.c
+++ b/libc/upstream-openbsd/lib/libc/string/strncmp.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strncmp.c,v 1.8 2014/06/10 04:17:37 deraadt Exp $	*/
+/*	$OpenBSD: strncmp.c,v 1.9 2015/08/31 02:53:57 guenther Exp $	*/
 
 /*
  * Copyright (c) 1989 The Regents of the University of California.
@@ -45,3 +45,4 @@
 	} while (--n != 0);
 	return (0);
 }
+DEF_STRONG(strncmp);
diff --git a/libc/upstream-openbsd/lib/libc/string/strncpy.c b/libc/upstream-openbsd/lib/libc/string/strncpy.c
index e83c7e5..ad9dc84 100644
--- a/libc/upstream-openbsd/lib/libc/string/strncpy.c
+++ b/libc/upstream-openbsd/lib/libc/string/strncpy.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strncpy.c,v 1.7 2014/06/10 04:17:37 deraadt Exp $	*/
+/*	$OpenBSD: strncpy.c,v 1.8 2015/08/31 02:53:57 guenther Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -56,3 +56,4 @@
 	}
 	return (dst);
 }
+DEF_STRONG(strncpy);
diff --git a/libc/upstream-openbsd/lib/libc/string/strndup.c b/libc/upstream-openbsd/lib/libc/string/strndup.c
index 27701ac..a6e5bff 100644
--- a/libc/upstream-openbsd/lib/libc/string/strndup.c
+++ b/libc/upstream-openbsd/lib/libc/string/strndup.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strndup.c,v 1.1 2010/05/18 22:24:55 tedu Exp $	*/
+/*	$OpenBSD: strndup.c,v 1.2 2015/08/31 02:53:57 guenther Exp $	*/
 
 /*
  * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -37,3 +37,4 @@
 
 	return copy;
 }
+DEF_WEAK(strndup);
diff --git a/libc/upstream-openbsd/lib/libc/string/strpbrk.c b/libc/upstream-openbsd/lib/libc/string/strpbrk.c
index cd3b71c..336c22d 100644
--- a/libc/upstream-openbsd/lib/libc/string/strpbrk.c
+++ b/libc/upstream-openbsd/lib/libc/string/strpbrk.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strpbrk.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
+/*	$OpenBSD: strpbrk.c,v 1.6 2015/08/31 02:53:57 guenther Exp $ */
 /*
  * Copyright (c) 1985 Regents of the University of California.
  * All rights reserved.
@@ -46,3 +46,4 @@
 	}
 	return (NULL);
 }
+DEF_STRONG(strpbrk);
diff --git a/libc/upstream-openbsd/lib/libc/string/strsep.c b/libc/upstream-openbsd/lib/libc/string/strsep.c
index 2ffc4b4..97c3cbf 100644
--- a/libc/upstream-openbsd/lib/libc/string/strsep.c
+++ b/libc/upstream-openbsd/lib/libc/string/strsep.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strsep.c,v 1.7 2014/02/05 20:42:32 stsp Exp $	*/
+/*	$OpenBSD: strsep.c,v 1.8 2015/08/31 02:53:57 guenther Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993
@@ -68,3 +68,4 @@
 	}
 	/* NOTREACHED */
 }
+DEF_WEAK(strsep);
diff --git a/libc/upstream-openbsd/lib/libc/string/strspn.c b/libc/upstream-openbsd/lib/libc/string/strspn.c
index 385649c..0ce41cb 100644
--- a/libc/upstream-openbsd/lib/libc/string/strspn.c
+++ b/libc/upstream-openbsd/lib/libc/string/strspn.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strspn.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
+/*	$OpenBSD: strspn.c,v 1.6 2015/08/31 02:53:57 guenther Exp $ */
 /*
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
@@ -49,3 +49,4 @@
 			goto cont;
 	return (p - 1 - s1);
 }
+DEF_STRONG(strspn);
diff --git a/libc/upstream-openbsd/lib/libc/string/wcsstr.c b/libc/upstream-openbsd/lib/libc/string/wcsstr.c
index 669e340..6a7b0da 100644
--- a/libc/upstream-openbsd/lib/libc/string/wcsstr.c
+++ b/libc/upstream-openbsd/lib/libc/string/wcsstr.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: wcsstr.c,v 1.3 2005/08/08 08:05:37 espie Exp $	*/
+/*	$OpenBSD: wcsstr.c,v 1.5 2015/10/01 02:32:07 guenther Exp $	*/
 /*	$NetBSD: wcsstr.c,v 1.3 2003/03/05 20:18:17 tshiozak Exp $	*/
 
 /*-
@@ -43,7 +43,6 @@
 	const wchar_t *r;
 
 	if (!*little) {
-		/* LINTED interface specification */
 		return (wchar_t *)big;
 	}
 	if (wcslen(big) < wcslen(little))
@@ -61,10 +60,12 @@
 			r++;
 		}
 		if (!*q) {
-			/* LINTED interface specification */
 			return (wchar_t *)p;
 		}
 		p++;
 	}
 	return NULL;
 }
+#ifndef WCSWCS
+DEF_STRONG(wcsstr);
+#endif
diff --git a/libc/upstream-openbsd/lib/libc/string/wcswidth.c b/libc/upstream-openbsd/lib/libc/string/wcswidth.c
index 8ea1bdf..9f003f9 100644
--- a/libc/upstream-openbsd/lib/libc/string/wcswidth.c
+++ b/libc/upstream-openbsd/lib/libc/string/wcswidth.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: wcswidth.c,v 1.4 2011/04/04 18:16:24 stsp Exp $	*/
+/*	$OpenBSD: wcswidth.c,v 1.5 2015/09/12 16:23:14 guenther Exp $	*/
 /*	$NetBSD: wcswidth.c,v 1.2 2001/01/03 14:29:37 lukem Exp $	*/
 
 /*-
@@ -48,3 +48,4 @@
 
 	return w;
 }
+DEF_WEAK(wcswidth);
diff --git a/libc/upstream-openbsd/lib/libc/string/wmemcpy.c b/libc/upstream-openbsd/lib/libc/string/wmemcpy.c
index 9bbd836..cf02ab9 100644
--- a/libc/upstream-openbsd/lib/libc/string/wmemcpy.c
+++ b/libc/upstream-openbsd/lib/libc/string/wmemcpy.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: wmemcpy.c,v 1.3 2005/08/08 08:05:37 espie Exp $	*/
+/*	$OpenBSD: wmemcpy.c,v 1.4 2015/09/12 16:23:14 guenther Exp $	*/
 /*	$NetBSD: wmemcpy.c,v 1.2 2001/01/03 14:29:37 lukem Exp $	*/
 
 /*-
@@ -38,3 +38,4 @@
 
 	return (wchar_t *)memcpy(d, s, n * sizeof(wchar_t));
 }
+DEF_STRONG(wmemcpy);
diff --git a/libm/Android.bp b/libm/Android.bp
index 8947f4d..75e8957 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -63,7 +63,6 @@
         "upstream-freebsd/lib/msun/src/e_sinhf.c",
         "upstream-freebsd/lib/msun/src/e_sqrt.c",
         "upstream-freebsd/lib/msun/src/e_sqrtf.c",
-        "upstream-freebsd/lib/msun/src/imprecise.c",
         "upstream-freebsd/lib/msun/src/k_cos.c",
         "upstream-freebsd/lib/msun/src/k_cosf.c",
         "upstream-freebsd/lib/msun/src/k_exp.c",
@@ -209,6 +208,7 @@
         // Functionality not in the BSDs.
         "significandl.c",
         "sincos.c",
+        "fake_long_double.c",
 
         // Modified versions of BSD code.
         "signbit.c",
@@ -218,10 +218,6 @@
     ],
 
     multilib: {
-        lib32: {
-            srcs: ["fake_long_double.c"],
-        },
-
         lib64: {
             srcs: [
                 "upstream-freebsd/lib/msun/src/e_acosl.c",
diff --git a/libm/fake_long_double.c b/libm/fake_long_double.c
index 20148a3..fd983ed 100644
--- a/libm/fake_long_double.c
+++ b/libm/fake_long_double.c
@@ -17,12 +17,11 @@
 #include <float.h>
 #include <math.h>
 
-#ifndef __LP64__
-/*
- * The BSD "long double" functions are broken when sizeof(long double) == sizeof(double).
- * Android works around those cases by replacing the broken functions with our own trivial stubs
- * that call the regular "double" function.
- */
+#if !defined(__LP64__)
+
+// The BSD "long double" functions are broken when sizeof(long double) == sizeof(double).
+// Android works around those cases by replacing the broken functions with our own trivial stubs
+// that call the regular "double" function.
 
 long double copysignl(long double a1, long double a2) { return copysign(a1, a2); }
 long double fmaxl(long double a1, long double a2) { return fmax(a1, a2); }
@@ -40,3 +39,7 @@
 long double roundl(long double a1) { return round(a1); }
 
 #endif // __LP64__
+
+// FreeBSD doesn't have ld128 implementations of powl or tgammal, so both LP32 and LP64 need these.
+long double powl(long double x, long double y) { return pow(x, y); }
+long double tgammal(long double x) { return tgamma(x); }
diff --git a/libm/freebsd-compat.h b/libm/freebsd-compat.h
index a4dd6c2..5bdb9fa 100644
--- a/libm/freebsd-compat.h
+++ b/libm/freebsd-compat.h
@@ -28,7 +28,12 @@
 
 #define __warn_references(sym,msg) /* ignored */
 
-/* digittoint is in BSD's <ctype.h>. */
+// digittoint is in BSD's <ctype.h>, but not ours, so we have a secret
+// implementation in libm. We reuse parts of libm in the NDK's
+// libandroid_support, where it's a static library, so we want all our
+// "hidden" functions start with a double underscore --- being HIDDEN
+// in the ELF sense is not sufficient.
+#define digittoint __libm_digittoint
 int digittoint(char ch);
 
 #endif
diff --git a/libm/upstream-freebsd/lib/msun/src/imprecise.c b/libm/upstream-freebsd/lib/msun/src/imprecise.c
deleted file mode 100644
index 08cd239..0000000
--- a/libm/upstream-freebsd/lib/msun/src/imprecise.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*-
- * Copyright (c) 2013 David Chisnall
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <float.h>
-#include <math.h>
-
-/*
- * If long double is not the same size as double, then these will lose
- * precision and we should emit a warning whenever something links against
- * them.
- */
-#if (LDBL_MANT_DIG > 53)
-#define WARN_IMPRECISE(x) \
-	__warn_references(x, # x " has lower than advertised precision");
-#else
-#define WARN_IMPRECISE(x)
-#endif
-/*
- * Declare the functions as weak variants so that other libraries providing
- * real versions can override them.
- */
-#define	DECLARE_WEAK(x)\
-	__weak_reference(imprecise_## x, x);\
-	WARN_IMPRECISE(x)
-
-long double
-imprecise_powl(long double x, long double y)
-{
-
-	return pow(x, y);
-}
-DECLARE_WEAK(powl);
-
-#define DECLARE_IMPRECISE(f) \
-	long double imprecise_ ## f ## l(long double v) { return f(v); }\
-	DECLARE_WEAK(f ## l)
-
-DECLARE_IMPRECISE(tgamma);
diff --git a/tests/sys_ptrace_test.cpp b/tests/sys_ptrace_test.cpp
index 00322ec..78fcf2b 100644
--- a/tests/sys_ptrace_test.cpp
+++ b/tests/sys_ptrace_test.cpp
@@ -66,14 +66,28 @@
   long result = ptrace(PTRACE_GETHBPREGS, child, 0, &capabilities);
   if (result == -1) {
     EXPECT_EQ(EIO, errno);
+    GTEST_LOG_(INFO) << "Hardware debug support disabled at kernel configuration time.";
     return false;
   }
-  switch (feature) {
-    case HwFeature::Watchpoint:
-      return ((capabilities >> 8) & 0xff) > 0;
-    case HwFeature::Breakpoint:
-      return (capabilities & 0xff) > 0;
+  uint8_t hb_count = capabilities & 0xff;
+  capabilities >>= 8;
+  uint8_t wp_count = capabilities & 0xff;
+  capabilities >>= 8;
+  uint8_t max_wp_size = capabilities & 0xff;
+  if (max_wp_size == 0) {
+    GTEST_LOG_(INFO)
+        << "Kernel reports zero maximum watchpoint size. Hardware debug support missing.";
+    return false;
   }
+  if (feature == HwFeature::Watchpoint && wp_count == 0) {
+    GTEST_LOG_(INFO) << "Kernel reports zero hardware watchpoints";
+    return false;
+  }
+  if (feature == HwFeature::Breakpoint && hb_count == 0) {
+    GTEST_LOG_(INFO) << "Kernel reports zero hardware breakpoints";
+    return false;
+  }
+  return true;
 #elif defined(__aarch64__)
   user_hwdebug_state dreg_state;
   iovec iov;
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 109b92c..a81f112 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -759,6 +759,7 @@
   EXPECT_GT(_POSIX_TZNAME_MAX, 0);
   EXPECT_NE(-1, _POSIX_VDISABLE);
 
+  EXPECT_EQ(_POSIX_VERSION, _POSIX2_VERSION);
   EXPECT_GT(_POSIX2_BC_BASE_MAX, 0);
   EXPECT_GT(_POSIX2_BC_DIM_MAX, 0);
   EXPECT_GT(_POSIX2_BC_SCALE_MAX, 0);
@@ -784,7 +785,6 @@
   EXPECT_EQ(-1, _POSIX_SPAWN);
   EXPECT_EQ(-1, _POSIX_THREAD_ROBUST_PRIO_INHERIT);
 
-  EXPECT_EQ(-1, _POSIX2_VERSION);
   EXPECT_EQ(-1, _POSIX2_CHAR_TERM);
   EXPECT_EQ(-1, _POSIX2_C_DEV);
   EXPECT_EQ(-1, _POSIX2_LOCALEDEF);
diff --git a/tools/relocation_packer/src/elf_file.cc b/tools/relocation_packer/src/elf_file.cc
index 96e6efd..275e486 100644
--- a/tools/relocation_packer/src/elf_file.cc
+++ b/tools/relocation_packer/src/elf_file.cc
@@ -234,24 +234,22 @@
   }
 
   // Loading failed if we did not find the required special sections.
-  if (!found_relocations_section) {
-    LOG(ERROR) << "Missing or empty .rel.dyn or .rela.dyn section";
-    return false;
-  }
   if (!found_dynamic_section) {
     LOG(ERROR) << "Missing .dynamic section";
     return false;
   }
 
-  // Loading failed if we could not identify the relocations type.
-  if (!has_rel_relocations && !has_rela_relocations) {
-    LOG(ERROR) << "No relocations sections found";
-    return false;
-  }
-  if (has_rel_relocations && has_rela_relocations) {
-    LOG(ERROR) << "Multiple relocations sections with different types found, "
-               << "not currently supported";
-    return false;
+  if (found_relocations_section != nullptr) {
+    // Loading failed if we could not identify the relocations type.
+    if (!has_rel_relocations && !has_rela_relocations) {
+      LOG(ERROR) << "No relocations sections found";
+      return false;
+    }
+    if (has_rel_relocations && has_rela_relocations) {
+      LOG(ERROR) << "Multiple relocations sections with different types found, "
+                 << "not currently supported";
+      return false;
+    }
   }
 
   elf_ = elf;
@@ -682,6 +680,11 @@
     return false;
   }
 
+  if (relocations_section_ == nullptr) {
+    // There is nothing to do
+    return true;
+  }
+
   // Retrieve the current dynamic relocations section data.
   Elf_Data* data = GetSectionData(relocations_section_);
   // we always pack rela, because packed format is pretty much the same
@@ -831,6 +834,11 @@
     return false;
   }
 
+  if (relocations_section_ == nullptr) {
+    // There is nothing to do
+    return true;
+  }
+
   typename ELF::Shdr* section_header = ELF::getshdr(relocations_section_);
   // Retrieve the current packed android relocations section data.
   Elf_Data* data = GetSectionData(relocations_section_);