Remove a check for AIDs in the OEM range. am: c2c36b661c
am: fe1dc33b28
Change-Id: Ic2107c9550f368db0ada5cc3f680bf289734a812
diff --git a/README.md b/README.md
index 61314b6..ee83b08 100644
--- a/README.md
+++ b/README.md
@@ -327,19 +327,54 @@
32-bit ABI bugs
---------------
-This probably belongs in the NDK documentation rather than here, but these
-are the known ABI bugs in the 32-bit ABI:
+### `off_t` is 32-bit.
- * `time_t` is 32-bit. <http://b/5819737>. In the 64-bit ABI, time_t is
- 64-bit.
+On 32-bit Android, `off_t` is a signed 32-bit integer. This limits functions
+that use `off_t` to working on files no larger than 2GiB.
- * `off_t` is 32-bit. There is `off64_t`, and in newer releases there is
- almost-complete support for `_FILE_OFFSET_BITS`. Unfortunately our stdio
- implementation uses 32-bit offsets and -- worse -- function pointers to
- functions that use 32-bit offsets, so there's no good way to implement
- the last few pieces <http://b/24807045>. In the 64-bit ABI, off_t is
- off64_t.
+Android does not require the `_LARGEFILE_SOURCE` macro to be used to make
+`fseeko` and `ftello` available. Instead they're always available from API
+level 24 where they were introduced, and never available before then.
- * `sigset_t` is too small on ARM and x86 (but correct on MIPS), so support
- for real-time signals is broken. <http://b/5828899> In the 64-bit ABI,
- `sigset_t` is the correct size for every architecture.
+Android also does not require the `_LARGEFILE64_SOURCE` macro to be used
+to make `off64_t` and corresponding functions such as `ftruncate64` available.
+Instead, whatever subset of those functions was available at your target API
+level will be visible.
+
+There are a couple of exceptions to note. Firstly, `off64_t` and the single
+function `lseek64` were available right from the beginning in API 3. Secondly,
+Android has always silently inserted `O_LARGEFILE` into any open call, so if
+all you need are functions like `read` that don't take/return `off_t`, large
+files have always worked.
+
+Android support for `_FILE_OFFSET_BITS=64` (which turns `off_t` into `off64_t`
+and replaces each `off_t` function with its `off64_t` counterpart, such as
+`lseek` in the source becoming `lseek64` at runtime) was added late. Even when
+it became available for the platform, it wasn't available from the NDK until
+r15. Before NDK r15, `_FILE_OFFSET_BITS=64` silently did nothing: all code
+compiled with that was actually using a 32-bit `off_t`. With a new enough NDK,
+the situation becomes complicated. If you're targeting an API before 21, almost
+all functions that take an `off_t` become unavailable. You've asked for their
+64-bit equivalents, and none of them (except `lseek`/`lseek64`) exist. As you
+increase your target API level, you'll have more and more of the functions
+available. API 12 adds some of the `<unistd.h>` functions, API 21 adds `mmap`,
+and by API 24 you have everything including `<stdio.h>`. See the
+[linker map](libc/libc.map.txt) for full details.
+
+In the 64-bit ABI, `off_t` is always 64-bit.
+
+### `sigset_t` is too small for real-time signals.
+
+On 32-bit Android, `sigset_t` is too small for ARM and x86 (but correct for
+MIPS). This means that there is no support for real-time signals in 32-bit
+code.
+
+In the 64-bit ABI, `sigset_t` is the correct size for every architecture.
+
+### `time_t` is 32-bit.
+
+On 32-bit Android, `time_t` is 32-bit. The header `<time64.h>` and type
+`time64_t` exist as a workaround, but the kernel interfaces exposed on 32-bit
+Android all use the 32-bit `time_t`.
+
+In the 64-bit ABI, `time_t` is 64-bit.
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/pthread_benchmark.cpp b/benchmarks/pthread_benchmark.cpp
index bf4d6cb..d3c2de8 100644
--- a/benchmarks/pthread_benchmark.cpp
+++ b/benchmarks/pthread_benchmark.cpp
@@ -56,7 +56,7 @@
}
static void BM_pthread_once(benchmark::State& state) {
- pthread_once_t once = PTHREAD_ONCE_INIT;
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
pthread_once(&once, DummyPthreadOnceInitFunction);
while (state.KeepRunning()) {
diff --git a/benchmarks/string_benchmark.cpp b/benchmarks/string_benchmark.cpp
index 41306db..2ab65a8 100644
--- a/benchmarks/string_benchmark.cpp
+++ b/benchmarks/string_benchmark.cpp
@@ -18,85 +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(benchmark::State& state) {
+static void BM_string_memmove_non_overlapping(benchmark::State& state) {
const size_t nbytes = state.range(0);
- char* buf = new char[nbytes + 64];
- memset(buf, 'x', nbytes + 64);
+ 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(buf, buf + 1, nbytes); // Worst-case overlap.
+ memmove(dst_aligned, src_aligned, nbytes);
}
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
- delete[] buf;
}
-BENCHMARK(BM_string_memmove)->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);
+ 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_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_ALIGNED_ONEBUF;
+
+static void BM_string_memmove_overlap_src_before_dst(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+ 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_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_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);
+ 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_aligned, src_aligned);
+ dst_aligned[2] = '\0';
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+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);
+ 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_aligned, src_aligned);
+ dst_aligned[nbytes - 1] = '\0';
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+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);
+ 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_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_ALIGNED_TWOBUF;
+
+static void BM_string_strcpy(benchmark::State& state) {
+ const size_t nbytes = state.range(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_aligned, src_aligned);
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BENCHMARK(BM_string_strcpy)->AT_ALIGNED_TWOBUF;
+
+static void BM_string_strcmp(benchmark::State& state) {
+ const size_t nbytes = state.range(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_aligned, s2_aligned);
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+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 5a1c287..7b0ac23 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -123,6 +123,12 @@
cflags: ["-fno-stack-protector"],
}
+cc_library_static {
+ name: "libc_init_dynamic",
+ defaults: ["libc_defaults"],
+ srcs: ["bionic/libc_init_dynamic.cpp"],
+ cflags: ["-fno-stack-protector"],
+}
// ========================================================
// libc_tzcode.a - upstream 'tzcode' code
@@ -1324,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",
@@ -1346,15 +1359,14 @@
"bionic/clock_nanosleep.cpp",
"bionic/clone.cpp",
"bionic/close.cpp",
- "bionic/__cmsg_nxthdr.cpp",
"bionic/connect.cpp",
"bionic/ctype.cpp",
"bionic/dirent.cpp",
"bionic/dup2.cpp",
+ "bionic/environ.cpp",
"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",
@@ -1380,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",
@@ -1388,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",
@@ -1400,7 +1409,6 @@
"bionic/mblen.cpp",
"bionic/mbrtoc16.cpp",
"bionic/mbrtoc32.cpp",
- "bionic/mbstate.cpp",
"bionic/memmem.cpp",
"bionic/mempcpy.cpp",
"bionic/mkdir.cpp",
@@ -1408,9 +1416,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",
@@ -1437,7 +1444,6 @@
"bionic/semaphore.cpp",
"bionic/send.cpp",
"bionic/setegid.cpp",
- "bionic/__set_errno.cpp",
"bionic/seteuid.cpp",
"bionic/setpgrp.cpp",
"bionic/sigaction.cpp",
@@ -1463,21 +1469,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",
@@ -1487,6 +1496,7 @@
"bionic/unlink.cpp",
"bionic/wait.cpp",
"bionic/wchar.cpp",
+ "bionic/wchar_l.cpp",
"bionic/wcstod.cpp",
"bionic/wctype.cpp",
"bionic/wmempcpy.cpp",
@@ -1757,10 +1767,10 @@
"arch-common/bionic/crtbrand.S",
"bionic/icu.cpp",
"bionic/malloc_common.cpp",
- "bionic/libc_init_dynamic.cpp",
"bionic/NetdClient.cpp",
"arch-common/bionic/crtend_so.S",
],
+ whole_static_libs: ["libc_init_dynamic"],
},
required: ["tzdata"],
diff --git a/libc/NOTICE b/libc/NOTICE
index fcc3c85..ae98d1d 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -110,25 +110,6 @@
-------------------------------------------------------------------
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-
-Copyright 2006, The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
--------------------------------------------------------------------
-
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
@@ -881,22 +862,6 @@
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.
-
--------------------------------------------------------------------
-
-Copyright (C) 2015 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.
@@ -1286,35 +1251,6 @@
-------------------------------------------------------------------
-Copyright (c) 1983, 1993
- The Regents of the University of California. 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.
-4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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) 1985
The Regents of the University of California. All rights reserved.
@@ -2955,6 +2891,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
@@ -5432,32 +5387,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/SECCOMP_WHITELIST.TXT b/libc/SECCOMP_WHITELIST.TXT
index beffef9..0b9dad3 100644
--- a/libc/SECCOMP_WHITELIST.TXT
+++ b/libc/SECCOMP_WHITELIST.TXT
@@ -36,6 +36,9 @@
int rt_tgsigqueueinfo:int rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *uinfo) all
int restart_syscall:int restart_syscall() all
int getrandom:int getrandom(void *buf, size_t buflen, unsigned int flags) all
+int fstatat64|fstatat:newfstatat(int, const char*, struct stat*, int) mips64
+int fstat64|fstat:fstat(int, struct stat*) mips64
+int _flush_cache:cacheflush(char* addr, const int nbytes, const int op) mips64
# Needed for performance tools
int perf_event_open:perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, unsigned long flags) all
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 5ff3c64..d674630 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -143,7 +143,7 @@
int ___fchmodat:fchmodat(int, const char*, mode_t) all
int fchownat(int, const char*, uid_t, gid_t, int) all
int fstatat64|fstatat:fstatat64(int, const char*, struct stat*, int) arm,mips,x86
-int fstatat64|fstatat:newfstatat(int, const char*, struct stat*, int) arm64,mips64,x86_64
+int fstatat64|fstatat:newfstatat(int, const char*, struct stat*, int) arm64,x86_64
int linkat(int, const char*, int, const char*, int) all
int mkdirat(int, const char*, mode_t) all
int mknodat(int, const char*, mode_t, dev_t) all
@@ -187,7 +187,7 @@
int __statfs:statfs(const char*, struct statfs*) arm64,mips64,x86_64
int fstat64|fstat:fstat64(int, struct stat*) arm,mips,x86
-int fstat64|fstat:fstat(int, struct stat*) arm64,mips64,x86_64
+int fstat64|fstat:fstat(int, struct stat*) arm64,x86_64
# file system
int chdir(const char*) all
@@ -343,7 +343,7 @@
int cacheflush:__ARM_NR_cacheflush(long start, long end, long flags) arm
# MIPS-specific
-int _flush_cache:cacheflush(char* addr, const int nbytes, const int op) mips,mips64
+int _flush_cache:cacheflush(char* addr, const int nbytes, const int op) mips
int __set_tls:set_thread_area(void*) mips,mips64
# x86-specific
diff --git a/libc/arch-mips64/bionic/stat.cpp b/libc/arch-mips64/bionic/stat.cpp
index 29a50ed..63b6cd1 100644
--- a/libc/arch-mips64/bionic/stat.cpp
+++ b/libc/arch-mips64/bionic/stat.cpp
@@ -43,11 +43,11 @@
unsigned int st_pad1[3];
__kernel_off_t st_size;
unsigned int _st_atime;
- unsigned int st_atime_nsec;
+ unsigned int _st_atime_nsec;
unsigned int _st_mtime;
- unsigned int st_mtime_nsec;
+ unsigned int _st_mtime_nsec;
unsigned int _st_ctime;
- unsigned int st_ctime_nsec;
+ unsigned int _st_ctime_nsec;
unsigned int st_blksize;
unsigned int st_pad2;
unsigned long st_blocks;
@@ -65,11 +65,11 @@
st->st_blksize = static_cast<int>(s->st_blksize);
st->st_blocks = static_cast<long>(s->st_blocks);
st->st_atim.tv_sec = static_cast<time_t>(s->_st_atime);
- st->st_atim.tv_nsec = static_cast<long>(s->st_atime_nsec);
+ st->st_atim.tv_nsec = static_cast<long>(s->_st_atime_nsec);
st->st_mtim.tv_sec = static_cast<time_t>(s->_st_mtime);
- st->st_mtim.tv_nsec = static_cast<long>(s->st_mtime_nsec);
+ st->st_mtim.tv_nsec = static_cast<long>(s->_st_mtime_nsec);
st->st_ctim.tv_sec = static_cast<time_t>(s->_st_ctime);
- st->st_ctim.tv_nsec = static_cast<long>(s->st_ctime_nsec);
+ st->st_ctim.tv_nsec = static_cast<long>(s->_st_ctime_nsec);
}
int fstat(int fp, struct stat* st) {
diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp
index 372f385..99ff0c7 100644
--- a/libc/async_safe/async_safe_log.cpp
+++ b/libc/async_safe/async_safe_log.cpp
@@ -567,10 +567,9 @@
android_set_abort_message(msg);
}
-void async_safe_fatal(const char* fmt, ...) {
+void async_safe_fatal_no_abort(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
async_safe_fatal_va_list(nullptr, fmt, args);
va_end(args);
- abort();
}
diff --git a/libc/async_safe/include/async_safe/log.h b/libc/async_safe/include/async_safe/log.h
index f93f672..6fdb84f 100644
--- a/libc/async_safe/include/async_safe/log.h
+++ b/libc/async_safe/include/async_safe/log.h
@@ -33,6 +33,7 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
+#include <stdlib.h>
// These functions do not allocate memory to send data to the log.
@@ -65,9 +66,19 @@
};
// Formats a message to the log (priority 'fatal'), then aborts.
-__noreturn void async_safe_fatal(const char* _Nonnull fmt, ...) __printflike(1, 2);
+// Implemented as a macro so that async_safe_fatal isn't on the stack when we crash:
+// we appear to go straight from the caller to abort, saving an uninteresting stack
+// frame.
+#define async_safe_fatal(...) \
+ do { \
+ async_safe_fatal_no_abort(__VA_ARGS__); \
+ abort(); \
+ } while (0) \
-// This function does return, so callers that want to abort, must do so themselves.
+
+// These functions do return, so callers that want to abort, must do so themselves,
+// or use the macro above.
+void async_safe_fatal_no_abort(const char* _Nonnull fmt, ...) __printflike(1, 2);
#if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
void async_safe_fatal_va_list(
const char* _Nullable prefix, const char* _Nonnull fmt, va_list);
diff --git a/libc/bionic/__errno.cpp b/libc/bionic/__errno.cpp
index c9c1605..32e7a52 100644
--- a/libc/bionic/__errno.cpp
+++ b/libc/bionic/__errno.cpp
@@ -31,6 +31,6 @@
#include "private/bionic_tls.h"
-volatile int* __errno() {
+int* __errno() {
return reinterpret_cast<int*>(&(__get_tls()[TLS_SLOT_ERRNO]));
}
diff --git a/libc/bionic/c16rtomb.cpp b/libc/bionic/c16rtomb.cpp
index 77512be..93749c6 100644
--- a/libc/bionic/c16rtomb.cpp
+++ b/libc/bionic/c16rtomb.cpp
@@ -50,18 +50,18 @@
mbstate_set_byte(state, 2, (c32 & 0x00ff00) >> 8);
return 0;
} else if (is_low_surrogate(c16)) {
- return reset_and_return_illegal(EINVAL, state);
+ return mbstate_reset_and_return_illegal(EINVAL, state);
} else {
return c32rtomb(s, static_cast<char32_t>(c16), state);
}
} else {
if (!is_low_surrogate(c16)) {
- return reset_and_return_illegal(EINVAL, state);
+ return mbstate_reset_and_return_illegal(EINVAL, state);
}
char32_t c32 = ((mbstate_get_byte(state, 3) << 16) |
(mbstate_get_byte(state, 2) << 8) |
(c16 & ~0xdc00)) + 0x10000;
- return reset_and_return(c32rtomb(s, c32, NULL), state);
+ return mbstate_reset_and_return(c32rtomb(s, c32, NULL), state);
}
}
diff --git a/libc/bionic/c32rtomb.cpp b/libc/bionic/c32rtomb.cpp
index d3231c0..ebe9cd3 100644
--- a/libc/bionic/c32rtomb.cpp
+++ b/libc/bionic/c32rtomb.cpp
@@ -38,7 +38,7 @@
if (s == NULL) {
// Equivalent to c32rtomb(buf, U'\0', ps).
- return reset_and_return(1, state);
+ return mbstate_reset_and_return(1, state);
}
// POSIX states that if char32_t is a null wide character, a null byte shall
@@ -47,11 +47,11 @@
// stored.
if (c32 == U'\0') {
*s = '\0';
- reset_and_return(1, state);
+ return mbstate_reset_and_return(1, state);
}
if (!mbsinit(state)) {
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if ((c32 & ~0x7f) == 0) {
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/libc/bionic/environ.cpp
similarity index 64%
rename from libc/arch-arm/include/machine/cpu-features.h
rename to libc/bionic/environ.cpp
index fc8c80d..363c1fd 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/libc/bionic/environ.cpp
@@ -25,24 +25,9 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef _ARM_MACHINE_CPU_FEATURES_H
-#define _ARM_MACHINE_CPU_FEATURES_H
-/* __ARM_ARCH__ is a number corresponding to the ARM revision
- * we're going to support. Our toolchain doesn't define __ARM_ARCH__
- * so try to guess it.
- */
-#ifndef __ARM_ARCH__
-# if defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ || \
- defined __ARM_ARCH_7R__ || defined __ARM_ARCH_7M__
-# define __ARM_ARCH__ 7
-# elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ || \
- defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6Z__ || \
- defined __ARM_ARCH_6KZ__ || defined __ARM_ARCH_6T2__
-# define __ARM_ARCH__ 6
-# else
-# error Unknown or unsupported ARM architecture
-# endif
-#endif
+#include <unistd.h>
-#endif /* _ARM_MACHINE_CPU_FEATURES_H */
+// Keep that variable in separate .o file to make sure programs which define
+// their own "environ" are compileable.
+char** environ;
diff --git a/libc/bionic/fts.c b/libc/bionic/fts.c
index 31a4b2f..a43c8c9 100644
--- a/libc/bionic/fts.c
+++ b/libc/bionic/fts.c
@@ -32,6 +32,7 @@
#include <sys/param.h>
#include <sys/stat.h>
+#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
@@ -719,7 +720,8 @@
/* Build a file name for fts_stat to stat. */
if (ISSET(FTS_NOCHDIR)) {
p->fts_accpath = p->fts_path;
- memmove(cp, p->fts_name, p->fts_namelen + 1);
+ assert(cp && "cp should be non-null if FTS_NOCHDIR is set");
+ memmove(cp, p->fts_name, p->fts_namelen + 1); // NOLINT
p->fts_info = fts_stat(sp, p, 0, dirfd(dirp));
} else {
p->fts_accpath = p->fts_name;
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index e051762..48fd670 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -59,9 +59,6 @@
// Not public, but well-known in the BSDs.
const char* __progname;
-// Declared in <unistd.h>.
-char** environ;
-
#if defined(__i386__)
__attribute__((__naked__)) static void __libc_int0x80() {
__asm__ volatile("int $0x80; ret");
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 43bca30..7c73950 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -61,6 +61,21 @@
extern int __cxa_atexit(void (*)(void *), void *, void *);
};
+// We need a helper function for __libc_preinit because compiling with LTO may
+// inline functions requiring a stack protector check, but __stack_chk_guard is
+// not initialized at the start of __libc_preinit. __libc_preinit_impl will run
+// after __stack_chk_guard is initialized and therefore can safely have a stack
+// protector.
+__attribute__((noinline))
+static void __libc_preinit_impl(KernelArgumentBlock& args) {
+ __libc_init_globals(args);
+ __libc_init_common(args);
+
+ // Hooks for various libraries to let them know that we're starting up.
+ __libc_globals.mutate(__libc_init_malloc);
+ netdClientInit();
+}
+
// We flag the __libc_preinit function as a constructor to ensure
// that its address is listed in libc.so's .init_array section.
// This ensures that the function is called by the dynamic linker
@@ -79,12 +94,7 @@
// thread's TLS slot with that value. Initialize the local global stack guard with its value.
__stack_chk_guard = reinterpret_cast<uintptr_t>(tls[TLS_SLOT_STACK_GUARD]);
- __libc_init_globals(*args);
- __libc_init_common(*args);
-
- // Hooks for various libraries to let them know that we're starting up.
- __libc_globals.mutate(__libc_init_malloc);
- netdClientInit();
+ __libc_preinit_impl(*args);
}
// This function is called from the executable's _start entry point
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/mbrtoc16.cpp b/libc/bionic/mbrtoc16.cpp
index 6878a11..2180516 100644
--- a/libc/bionic/mbrtoc16.cpp
+++ b/libc/bionic/mbrtoc16.cpp
@@ -55,7 +55,7 @@
char16_t trail = mbstate_get_byte(state, 1) << 8 |
mbstate_get_byte(state, 0);
*pc16 = trail;
- return reset_and_return(mbstate_get_byte(state, 3), state);
+ return mbstate_reset_and_return(mbstate_get_byte(state, 3), state);
}
size_t mbrtoc16(char16_t* pc16, const char* s, size_t n, mbstate_t* ps) {
@@ -76,13 +76,13 @@
if (__MB_IS_ERR(nconv)) {
return nconv;
} else if (nconv == 0) {
- return reset_and_return(nconv, state);
+ return mbstate_reset_and_return(nconv, state);
} else if (c32 > 0x10ffff) {
// Input cannot be encoded as UTF-16.
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
} else if (c32 < 0x10000) {
*pc16 = static_cast<char16_t>(c32);
- return reset_and_return(nconv, state);
+ return mbstate_reset_and_return(nconv, state);
} else {
return begin_surrogate(c32, pc16, nconv, state);
}
diff --git a/libc/bionic/mbrtoc32.cpp b/libc/bionic/mbrtoc32.cpp
index bd40ecf..f004b78 100644
--- a/libc/bionic/mbrtoc32.cpp
+++ b/libc/bionic/mbrtoc32.cpp
@@ -41,7 +41,7 @@
// Full state verification is done when decoding the sequence (after we have
// all the bytes).
if (mbstate_get_byte(state, 3) != 0) {
- return reset_and_return_illegal(EINVAL, state);
+ return mbstate_reset_and_return_illegal(EINVAL, state);
}
if (s == NULL) {
@@ -98,7 +98,7 @@
lower_bound = 0x10000;
} else {
// Malformed input; input is not UTF-8. See RFC 3629.
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
// Fill in the state.
@@ -107,7 +107,7 @@
for (i = 0; i < MIN(bytes_wanted, n); i++) {
if (!mbsinit(state) && ((*s & 0xc0) != 0x80)) {
// Malformed input; bad characters in the middle of a character.
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
mbstate_set_byte(state, bytes_so_far + i, *s++);
}
@@ -125,14 +125,14 @@
if (c32 < lower_bound) {
// Malformed input; redundant encoding.
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if ((c32 >= 0xd800 && c32 <= 0xdfff) || c32 == 0xfffe || c32 == 0xffff) {
// Malformed input; invalid code points.
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if (pc32 != NULL) {
*pc32 = c32;
}
- return reset_and_return(c32 == U'\0' ? 0 : bytes_wanted, state);
+ return mbstate_reset_and_return(c32 == U'\0' ? 0 : bytes_wanted, state);
}
diff --git a/libc/bionic/sched_cpualloc.c b/libc/bionic/sched_cpualloc.c
index 30964bc..345de91 100644
--- a/libc/bionic/sched_cpualloc.c
+++ b/libc/bionic/sched_cpualloc.c
@@ -31,7 +31,10 @@
cpu_set_t* __sched_cpualloc(size_t count)
{
- return (cpu_set_t*) malloc(CPU_ALLOC_SIZE(count));
+ // The static analyzer complains that CPU_ALLOC_SIZE eventually expands to
+ // N * sizeof(unsigned long), which is incompatible with cpu_set_t. This is
+ // on purpose.
+ return (cpu_set_t*) malloc(CPU_ALLOC_SIZE(count)); // NOLINT
}
void __sched_cpufree(cpu_set_t* set)
diff --git a/libc/bionic/mbstate.cpp b/libc/bionic/stdlib_l.cpp
similarity index 62%
rename from libc/bionic/mbstate.cpp
rename to libc/bionic/stdlib_l.cpp
index cb327d8..18e9f86 100644
--- a/libc/bionic/mbstate.cpp
+++ b/libc/bionic/stdlib_l.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,32 +26,34 @@
* SUCH DAMAGE.
*/
-#include "private/bionic_mbstate.h"
+#include <stdlib.h>
+#include <xlocale.h>
-#include <errno.h>
-
-__LIBC_HIDDEN__ size_t mbstate_bytes_so_far(const mbstate_t* ps) {
- return
- (ps->__seq[2] != 0) ? 3 :
- (ps->__seq[1] != 0) ? 2 :
- (ps->__seq[0] != 0) ? 1 : 0;
+double strtod_l(const char* s, char** end_ptr, locale_t) {
+ return strtod(s, end_ptr);
}
-__LIBC_HIDDEN__ void mbstate_set_byte(mbstate_t* ps, int i, char byte) {
- ps->__seq[i] = static_cast<uint8_t>(byte);
+float strtof_l(const char* s, char** end_ptr, locale_t) {
+ return strtof(s, end_ptr);
}
-__LIBC_HIDDEN__ uint8_t mbstate_get_byte(const mbstate_t* ps, int n) {
- return ps->__seq[n];
+long strtol_l(const char* s, char** end_ptr, int base, locale_t) {
+ return strtol(s, end_ptr, base);
}
-__LIBC_HIDDEN__ size_t reset_and_return_illegal(int _errno, mbstate_t* ps) {
- errno = _errno;
- *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
- return __MB_ERR_ILLEGAL_SEQUENCE;
+long double strtold_l(const char* s, char** end_ptr, locale_t) {
+ return strtold(s, end_ptr);
}
-__LIBC_HIDDEN__ size_t reset_and_return(int _return, mbstate_t* ps) {
- *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
- return _return;
+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/arch-arm/include/machine/cpu-features.h b/libc/bionic/string_l.cpp
similarity index 62%
copy from libc/arch-arm/include/machine/cpu-features.h
copy to libc/bionic/string_l.cpp
index fc8c80d..66bfb0e 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/libc/bionic/string_l.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,24 +25,18 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef _ARM_MACHINE_CPU_FEATURES_H
-#define _ARM_MACHINE_CPU_FEATURES_H
-/* __ARM_ARCH__ is a number corresponding to the ARM revision
- * we're going to support. Our toolchain doesn't define __ARM_ARCH__
- * so try to guess it.
- */
-#ifndef __ARM_ARCH__
-# if defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ || \
- defined __ARM_ARCH_7R__ || defined __ARM_ARCH_7M__
-# define __ARM_ARCH__ 7
-# elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ || \
- defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6Z__ || \
- defined __ARM_ARCH_6KZ__ || defined __ARM_ARCH_6T2__
-# define __ARM_ARCH__ 6
-# else
-# error Unknown or unsupported ARM architecture
-# endif
-#endif
+#include <string.h>
+#include <xlocale.h>
-#endif /* _ARM_MACHINE_CPU_FEATURES_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/arch-arm/include/machine/cpu-features.h b/libc/bionic/strings_l.cpp
similarity index 62%
copy from libc/arch-arm/include/machine/cpu-features.h
copy to libc/bionic/strings_l.cpp
index fc8c80d..0983ab1 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/libc/bionic/strings_l.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,24 +25,14 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef _ARM_MACHINE_CPU_FEATURES_H
-#define _ARM_MACHINE_CPU_FEATURES_H
-/* __ARM_ARCH__ is a number corresponding to the ARM revision
- * we're going to support. Our toolchain doesn't define __ARM_ARCH__
- * so try to guess it.
- */
-#ifndef __ARM_ARCH__
-# if defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ || \
- defined __ARM_ARCH_7R__ || defined __ARM_ARCH_7M__
-# define __ARM_ARCH__ 7
-# elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ || \
- defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6Z__ || \
- defined __ARM_ARCH_6KZ__ || defined __ARM_ARCH_6T2__
-# define __ARM_ARCH__ 6
-# else
-# error Unknown or unsupported ARM architecture
-# endif
-#endif
+#include <strings.h>
+#include <xlocale.h>
-#endif /* _ARM_MACHINE_CPU_FEATURES_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/termios.cpp b/libc/bionic/termios.cpp
index 44ae643..5fe8eb0 100644
--- a/libc/bionic/termios.cpp
+++ b/libc/bionic/termios.cpp
@@ -26,93 +26,21 @@
* SUCH DAMAGE.
*/
-#include <errno.h>
#include <termios.h>
#include <unistd.h>
-static speed_t cfgetspeed(const termios* s) {
- return (s->c_cflag & CBAUD);
-}
+// Most of termios was missing in the platform until L, but available as inlines in the NDK.
+// We share definitions with the NDK to avoid bugs (https://github.com/android-ndk/ndk/issues/441).
+#define __BIONIC_TERMIOS_INLINE /* Out of line. */
+#include <bits/termios_inlines.h>
-speed_t cfgetispeed(const termios* s) {
- return cfgetspeed(s);
-}
-
-speed_t cfgetospeed(const termios* s) {
- return cfgetspeed(s);
-}
-
-void cfmakeraw(termios* s) {
- s->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
- s->c_oflag &= ~OPOST;
- s->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
- s->c_cflag &= ~(CSIZE|PARENB);
- s->c_cflag |= CS8;
-}
-
-int cfsetispeed(termios* s, speed_t speed) {
- return cfsetspeed(s, speed);
-}
-
-int cfsetospeed(termios* s, speed_t speed) {
- return cfsetspeed(s, speed);
-}
-
-int cfsetspeed(termios* s, speed_t speed) {
- // TODO: check 'speed' is valid.
- s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);
- return 0;
-}
-
-int tcdrain(int fd) {
- // A non-zero argument to TCSBRK means "don't send a break".
- // The drain is a side-effect of the ioctl!
- return ioctl(fd, TCSBRK, static_cast<unsigned long>(1));
-}
-
-int tcflow(int fd, int action) {
- return ioctl(fd, TCXONC, static_cast<unsigned long>(action));
-}
-
-int tcflush(int fd, int queue) {
- return ioctl(fd, TCFLSH, static_cast<unsigned long>(queue));
-}
-
-int tcgetattr(int fd, termios* s) {
- return ioctl(fd, TCGETS, s);
-}
-
-pid_t tcgetsid(int fd) {
- pid_t sid;
- if (ioctl(fd, TIOCGSID, &sid) == -1) {
- return -1;
- }
- return sid;
-}
-
-int tcsendbreak(int fd, int duration) {
- return ioctl(fd, TCSBRKP, static_cast<unsigned long>(duration));
-}
-
-int tcsetattr(int fd, int optional_actions, const termios* s) {
- int cmd;
- switch (optional_actions) {
- case TCSANOW: cmd = TCSETS; break;
- case TCSADRAIN: cmd = TCSETSW; break;
- case TCSAFLUSH: cmd = TCSETSF; break;
- default: errno = EINVAL; return -1;
- }
- return ioctl(fd, cmd, s);
-}
-
+// Actually declared in <unistd.h>, present on all API levels.
pid_t tcgetpgrp(int fd) {
pid_t pid;
- if (ioctl(fd, TIOCGPGRP, &pid) == -1) {
- return -1;
- }
- return pid;
+ return (ioctl(fd, TIOCGPGRP, &pid) == -1) ? -1 : pid;
}
+// Actually declared in <unistd.h>, present on all API levels.
int tcsetpgrp(int fd, pid_t pid) {
return ioctl(fd, TIOCSPGRP, &pid);
}
diff --git a/libc/bionic/wchar.cpp b/libc/bionic/wchar.cpp
index 7717e10..62023d6 100644
--- a/libc/bionic/wchar.cpp
+++ b/libc/bionic/wchar.cpp
@@ -74,7 +74,7 @@
// character appears as anything but the first byte of a
// multibyte sequence. Check now to avoid doing it in the loops.
if (nmc > 0 && mbstate_bytes_so_far(state) > 0 && static_cast<uint8_t>((*src)[0]) < 0x80) {
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
// Measure only?
@@ -83,23 +83,23 @@
if (static_cast<uint8_t>((*src)[i]) < 0x80) {
// Fast path for plain ASCII characters.
if ((*src)[i] == '\0') {
- return reset_and_return(o, state);
+ return mbstate_reset_and_return(o, state);
}
r = 1;
} else {
r = mbrtowc(NULL, *src + i, nmc - i, state);
if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if (r == __MB_ERR_INCOMPLETE_SEQUENCE) {
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if (r == 0) {
- return reset_and_return(o, state);
+ return mbstate_reset_and_return(o, state);
}
}
}
- return reset_and_return(o, state);
+ return mbstate_reset_and_return(o, state);
}
// Actually convert, updating `dst` and `src`.
@@ -110,26 +110,26 @@
r = 1;
if ((*src)[i] == '\0') {
*src = nullptr;
- return reset_and_return(o, state);
+ return mbstate_reset_and_return(o, state);
}
} else {
r = mbrtowc(dst + o, *src + i, nmc - i, state);
if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
*src += i;
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if (r == __MB_ERR_INCOMPLETE_SEQUENCE) {
*src += nmc;
- return reset_and_return(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
if (r == 0) {
*src = NULL;
- return reset_and_return(o, state);
+ return mbstate_reset_and_return(o, state);
}
}
}
*src += i;
- return reset_and_return(o, state);
+ return mbstate_reset_and_return(o, state);
}
size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps) {
@@ -149,7 +149,7 @@
mbstate_t* state = (ps == NULL) ? &__private_state : ps;
if (!mbsinit(state)) {
- return reset_and_return_illegal(EILSEQ, state);
+ return mbstate_reset_and_return_illegal(EILSEQ, state);
}
char buf[MB_LEN_MAX];
@@ -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/bionic/wctype.cpp b/libc/bionic/wctype.cpp
index 77f8dde..8e2acef 100644
--- a/libc/bionic/wctype.cpp
+++ b/libc/bionic/wctype.cpp
@@ -36,6 +36,23 @@
#include "private/icu.h"
+enum {
+ WC_TYPE_INVALID = 0,
+ WC_TYPE_ALNUM,
+ WC_TYPE_ALPHA,
+ WC_TYPE_BLANK,
+ WC_TYPE_CNTRL,
+ WC_TYPE_DIGIT,
+ WC_TYPE_GRAPH,
+ WC_TYPE_LOWER,
+ WC_TYPE_PRINT,
+ WC_TYPE_PUNCT,
+ WC_TYPE_SPACE,
+ WC_TYPE_UPPER,
+ WC_TYPE_XDIGIT,
+ WC_TYPE_MAX
+};
+
static bool __icu_hasBinaryProperty(wint_t wc, UProperty property, int (*fallback)(int)) {
typedef UBool (*FnT)(UChar32, UProperty);
static auto u_hasBinaryProperty = reinterpret_cast<FnT>(__find_icu_symbol("u_hasBinaryProperty"));
diff --git a/libc/include/android/legacy_signal_inlines.h b/libc/include/android/legacy_signal_inlines.h
index a5d3a6f..09db2a6 100644
--- a/libc/include/android/legacy_signal_inlines.h
+++ b/libc/include/android/legacy_signal_inlines.h
@@ -37,10 +37,10 @@
__BEGIN_DECLS
-sighandler_t bsd_signal(int signum, sighandler_t handler) __REMOVED_IN(21);
-
#if __ANDROID_API__ < __ANDROID_API_L__
+sighandler_t bsd_signal(int signum, sighandler_t handler) __REMOVED_IN(21);
+
/* These weren't introduced until L. */
int __libc_current_sigrtmax() __attribute__((__weak__)) __VERSIONER_NO_GUARD;
int __libc_current_sigrtmin() __attribute__((__weak__)) __VERSIONER_NO_GUARD;
diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index e211de5..82186c7 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -36,6 +36,8 @@
__BEGIN_DECLS
+__noreturn void _Exit(int) __RENAME(_exit);
+
static __inline float strtof(const char *nptr, char **endptr) {
return (float)strtod(nptr, endptr);
}
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/libc/include/android/legacy_strings_inlines.h
similarity index 62%
copy from libc/arch-arm/include/machine/cpu-features.h
copy to libc/include/android/legacy_strings_inlines.h
index fc8c80d..6679c30 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/libc/include/android/legacy_strings_inlines.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,24 +25,20 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef _ARM_MACHINE_CPU_FEATURES_H
-#define _ARM_MACHINE_CPU_FEATURES_H
-/* __ARM_ARCH__ is a number corresponding to the ARM revision
- * we're going to support. Our toolchain doesn't define __ARM_ARCH__
- * so try to guess it.
- */
-#ifndef __ARM_ARCH__
-# if defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ || \
- defined __ARM_ARCH_7R__ || defined __ARM_ARCH_7M__
-# define __ARM_ARCH__ 7
-# elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ || \
- defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6Z__ || \
- defined __ARM_ARCH_6KZ__ || defined __ARM_ARCH_6T2__
-# define __ARM_ARCH__ 6
-# else
-# error Unknown or unsupported ARM architecture
-# endif
+#ifndef _ANDROID_LEGACY_STRINGS_INLINES_H_
+#define _ANDROID_LEGACY_STRINGS_INLINES_H_
+
+#include <strings.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#if defined(__i386__) && __ANDROID_API__ < __ANDROID_API_J_MR2__
+/* Everyone except x86 had ffs since the beginning. */
+static __inline int ffs(int __n) { return __builtin_ffs(__n); }
#endif
-#endif /* _ARM_MACHINE_CPU_FEATURES_H */
+__END_DECLS
+
+#endif
diff --git a/libc/include/android/legacy_termios_inlines.h b/libc/include/android/legacy_termios_inlines.h
index 02e9429..4ed56f0 100644
--- a/libc/include/android/legacy_termios_inlines.h
+++ b/libc/include/android/legacy_termios_inlines.h
@@ -36,74 +36,8 @@
#include <linux/termios.h>
#if __ANDROID_API__ < __ANDROID_API_L__
-
-__BEGIN_DECLS
-
-static __inline int tcgetattr(int fd, struct termios *s) {
- return ioctl(fd, TCGETS, s);
-}
-
-static __inline int tcsetattr(int fd, int __opt, const struct termios *s) {
- return ioctl(fd, __opt, (void *)s);
-}
-
-static __inline int tcflow(int fd, int action) {
- return ioctl(fd, TCXONC, (void *)(intptr_t)action);
-}
-
-static __inline int tcflush(int fd, int __queue) {
- return ioctl(fd, TCFLSH, (void *)(intptr_t)__queue);
-}
-
-static __inline pid_t tcgetsid(int fd) {
- pid_t _pid;
- return ioctl(fd, TIOCGSID, &_pid) ? (pid_t)-1 : _pid;
-}
-
-static __inline int tcsendbreak(int fd, int __duration) {
- return ioctl(fd, TCSBRKP, (void *)(uintptr_t)__duration);
-}
-
-static __inline speed_t cfgetospeed(const struct termios *s) {
- return (speed_t)(s->c_cflag & CBAUD);
-}
-
-static __inline int cfsetospeed(struct termios *s, speed_t speed) {
- s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);
- return 0;
-}
-
-static __inline speed_t cfgetispeed(const struct termios *s) {
- return (speed_t)(s->c_cflag & CBAUD);
-}
-
-static __inline int cfsetispeed(struct termios *s, speed_t speed) {
- s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);
- return 0;
-}
-
-static __inline void cfmakeraw(struct termios *s) {
- s->c_iflag &=
- ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
- s->c_oflag &= ~OPOST;
- s->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
- s->c_cflag &= ~(CSIZE | PARENB);
- s->c_cflag |= CS8;
-}
-
-static __inline int cfsetspeed(struct termios* s, speed_t speed) {
- // TODO: check 'speed' is valid.
- s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);
- return 0;
-}
-
-static __inline int tcdrain(int fd) {
- // A non-zero argument to TCSBRK means "don't send a break".
- // The drain is a side-effect of the ioctl!
- return ioctl(fd, TCSBRK, __BIONIC_CAST(static_cast, unsigned long, 1));
-}
-
-__END_DECLS
-
+#define __BIONIC_TERMIOS_INLINE static __inline
+#include <bits/termios_inlines.h>
#endif
+
#endif /* _ANDROID_LEGACY_TERMIOS_INLINES_H_ */
diff --git a/libc/include/arpa/ftp.h b/libc/include/arpa/ftp.h
new file mode 100644
index 0000000..081c037
--- /dev/null
+++ b/libc/include/arpa/ftp.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1983, 1989, 1993
+ * The Regents of the University of California. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)ftp.h 8.1 (Berkeley) 6/2/93
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _ARPA_FTP_H_
+#define _ARPA_FTP_H_
+
+/* Definitions for FTP; see RFC-765. */
+
+/*
+ * Reply codes.
+ */
+#define PRELIM 1 /* positive preliminary */
+#define COMPLETE 2 /* positive completion */
+#define CONTINUE 3 /* positive intermediate */
+#define TRANSIENT 4 /* transient negative completion */
+#define ERROR 5 /* permanent negative completion */
+
+/*
+ * Type codes
+ */
+#define TYPE_A 1 /* ASCII */
+#define TYPE_E 2 /* EBCDIC */
+#define TYPE_I 3 /* image */
+#define TYPE_L 4 /* local byte size */
+
+#ifdef FTP_NAMES
+char *typenames[] = {"0", "ASCII", "EBCDIC", "Image", "Local" };
+#endif
+
+/*
+ * Form codes
+ */
+#define FORM_N 1 /* non-print */
+#define FORM_T 2 /* telnet format effectors */
+#define FORM_C 3 /* carriage control (ASA) */
+#ifdef FTP_NAMES
+char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" };
+#endif
+
+/*
+ * Structure codes
+ */
+#define STRU_F 1 /* file (no record structure) */
+#define STRU_R 2 /* record structure */
+#define STRU_P 3 /* page structure */
+#ifdef FTP_NAMES
+char *strunames[] = {"0", "File", "Record", "Page" };
+#endif
+
+/*
+ * Mode types
+ */
+#define MODE_S 1 /* stream */
+#define MODE_B 2 /* block */
+#define MODE_C 3 /* compressed */
+#ifdef FTP_NAMES
+char *modenames[] = {"0", "Stream", "Block", "Compressed" };
+#endif
+
+/*
+ * Record Tokens
+ */
+#define REC_ESC '\377' /* Record-mode Escape */
+#define REC_EOR '\001' /* Record-mode End-of-Record */
+#define REC_EOF '\002' /* Record-mode End-of-File */
+
+/*
+ * Block Header
+ */
+#define BLK_EOR 0x80 /* Block is End-of-Record */
+#define BLK_EOF 0x40 /* Block is End-of-File */
+#define BLK_ERRORS 0x20 /* Block is suspected of containing errors */
+#define BLK_RESTART 0x10 /* Block is Restart Marker */
+
+#define BLK_BYTECOUNT 2 /* Bytes in this block */
+
+#endif /* !_FTP_H_ */
diff --git a/libc/include/arpa/telnet.h b/libc/include/arpa/telnet.h
index 594dc7a..758e9b8 100644
--- a/libc/include/arpa/telnet.h
+++ b/libc/include/arpa/telnet.h
@@ -10,7 +10,7 @@
* 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.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -27,12 +27,11 @@
* SUCH DAMAGE.
*
* @(#)telnet.h 8.2 (Berkeley) 12/15/93
+ * $FreeBSD$
*/
-#ifndef _ARPA_TELNET_H
-#define _ARPA_TELNET_H 1
-
-#include <sys/cdefs.h>
+#ifndef _ARPA_TELNET_H_
+#define _ARPA_TELNET_H_
/*
* Definitions for the TELNET protocol.
@@ -61,11 +60,14 @@
#define SYNCH 242 /* for telfunc calls */
#ifdef TELCMDS
-char *telcmds[] = {
+const char *telcmds[] = {
"EOF", "SUSP", "ABORT", "EOR",
"SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
- "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0,
+ "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC",
+ 0
};
+#else
+extern char *telcmds[];
#endif
#define TELCMD_FIRST xEOF
@@ -92,7 +94,7 @@
#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
-#define TELOPT_XASCII 17 /* extended ascii character set */
+#define TELOPT_XASCII 17 /* extended ascic character set */
#define TELOPT_LOGOUT 18 /* force logout */
#define TELOPT_BM 19 /* byte macro */
#define TELOPT_DET 20 /* data entry terminal */
@@ -115,10 +117,14 @@
#define TELOPT_AUTHENTICATION 37/* Authenticate */
#define TELOPT_ENCRYPT 38 /* Encryption option */
#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */
+#define TELOPT_TN3270E 40 /* RFC2355 - TN3270 Enhancements */
+#define TELOPT_CHARSET 42 /* RFC2066 - Charset */
+#define TELOPT_COMPORT 44 /* RFC2217 - Com Port Control */
+#define TELOPT_KERMIT 47 /* RFC2840 - Kermit */
#define TELOPT_EXOPL 255 /* extended-options-list */
-#define NTELOPTS (1+TELOPT_NEW_ENVIRON)
+#define NTELOPTS (1+TELOPT_KERMIT)
#ifdef TELOPTS
const char *telopts[NTELOPTS+1] = {
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
@@ -130,11 +136,12 @@
"TACACS UID", "OUTPUT MARKING", "TTYLOC",
"3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
"LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
- "ENCRYPT", "NEW-ENVIRON",
- 0,
+ "ENCRYPT", "NEW-ENVIRON", "TN3270E", "XAUTH", "CHARSET",
+ "RSP", "COM-PORT", "SLE", "STARTTLS", "KERMIT",
+ 0
};
#define TELOPT_FIRST TELOPT_BINARY
-#define TELOPT_LAST TELOPT_NEW_ENVIRON
+#define TELOPT_LAST TELOPT_KERMIT
#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
#endif
@@ -192,20 +199,39 @@
#define SLC_XOFF 16
#define SLC_FORW1 17
#define SLC_FORW2 18
+#define SLC_MCL 19
+#define SLC_MCR 20
+#define SLC_MCWL 21
+#define SLC_MCWR 22
+#define SLC_MCBOL 23
+#define SLC_MCEOL 24
+#define SLC_INSRT 25
+#define SLC_OVER 26
+#define SLC_ECR 27
+#define SLC_EWR 28
+#define SLC_EBOL 29
+#define SLC_EEOL 30
-#define NSLC 18
+#define NSLC 30
/*
* For backwards compatibility, we define SLC_NAMES to be the
* list of names if SLC_NAMES is not defined.
*/
-#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
- "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
- "LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0,
+#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
+ "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
+ "LNEXT", "XON", "XOFF", "FORW1", "FORW2", \
+ "MCL", "MCR", "MCWL", "MCWR", "MCBOL", \
+ "MCEOL", "INSRT", "OVER", "ECR", "EWR", \
+ "EBOL", "EEOL", \
+ 0
+
#ifdef SLC_NAMES
const char *slc_names[] = {
SLC_NAMELIST
};
+#else
+extern char *slc_names[];
#define SLC_NAMES SLC_NAMELIST
#endif
@@ -256,14 +282,18 @@
#define AUTHTYPE_KERBEROS_V5 2
#define AUTHTYPE_SPX 3
#define AUTHTYPE_MINK 4
-#define AUTHTYPE_CNT 5
+#define AUTHTYPE_SRA 6
+#define AUTHTYPE_CNT 7
#define AUTHTYPE_TEST 99
#ifdef AUTH_NAMES
const char *authtype_names[] = {
- "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
+ "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", NULL, "SRA",
+ 0
};
+#else
+extern char *authtype_names[];
#endif
#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
@@ -278,7 +308,7 @@
#define ENCRYPT_START 3 /* Am starting to send encrypted */
#define ENCRYPT_END 4 /* Am ending encrypted */
#define ENCRYPT_REQSTART 5 /* Request you start encrypting */
-#define ENCRYPT_REQEND 6 /* Request you send encrypting */
+#define ENCRYPT_REQEND 6 /* Request you end encrypting */
#define ENCRYPT_ENC_KEYID 7
#define ENCRYPT_DEC_KEYID 8
#define ENCRYPT_CNT 9
@@ -292,11 +322,15 @@
const char *encrypt_names[] = {
"IS", "SUPPORT", "REPLY", "START", "END",
"REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
- 0,
+ 0
};
const char *enctype_names[] = {
- "ANY", "DES_CFB64", "DES_OFB64", 0,
+ "ANY", "DES_CFB64", "DES_OFB64",
+ 0
};
+#else
+extern char *encrypt_names[];
+extern char *enctype_names[];
#endif
@@ -306,4 +340,4 @@
#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
#define ENCTYPE_NAME(x) enctype_names[x]
-#endif /* arpa/telnet.h */
+#endif /* !_TELNET_H_ */
diff --git a/libc/include/arpa/tftp.h b/libc/include/arpa/tftp.h
new file mode 100644
index 0000000..20733ec
--- /dev/null
+++ b/libc/include/arpa/tftp.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)tftp.h 8.1 (Berkeley) 6/2/93
+ * $FreeBSD$
+ */
+
+#ifndef _ARPA_TFTP_H_
+#define _ARPA_TFTP_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * Trivial File Transfer Protocol (IEN-133)
+ */
+#define SEGSIZE 512 /* data segment size */
+
+/*
+ * Packet types.
+ */
+#define RRQ 01 /* read request */
+#define WRQ 02 /* write request */
+#define DATA 03 /* data packet */
+#define ACK 04 /* acknowledgement */
+#define ERROR 05 /* error code */
+#define OACK 06 /* option acknowledgement */
+
+struct tftphdr {
+ unsigned short th_opcode; /* packet type */
+ union {
+ unsigned short tu_block; /* block # */
+ unsigned short tu_code; /* error code */
+ char tu_stuff[1]; /* request packet stuff */
+ } __packed th_u;
+ char th_data[1]; /* data or error string */
+} __packed;
+
+#define th_block th_u.tu_block
+#define th_code th_u.tu_code
+#define th_stuff th_u.tu_stuff
+#define th_msg th_data
+
+/*
+ * Error codes.
+ */
+#define EUNDEF 0 /* not defined */
+#define ENOTFOUND 1 /* file not found */
+#define EACCESS 2 /* access violation */
+#define ENOSPACE 3 /* disk full or allocation exceeded */
+#define EBADOP 4 /* illegal TFTP operation */
+#define EBADID 5 /* unknown transfer ID */
+#define EEXISTS 6 /* file already exists */
+#define ENOUSER 7 /* no such user */
+#define EOPTNEG 8 /* option negotiation failed */
+
+#endif /* !_TFTP_H_ */
diff --git a/libc/include/bits/lockf.h b/libc/include/bits/lockf.h
index 655514d..c24f18b 100644
--- a/libc/include/bits/lockf.h
+++ b/libc/include/bits/lockf.h
@@ -40,7 +40,7 @@
__BEGIN_DECLS
#if defined(__USE_FILE_OFFSET64)
-int lockf(int, int, off_t) __RENAME(lockf64);
+int lockf(int, int, off_t) __RENAME(lockf64) __INTRODUCED_IN(24);
#else
int lockf(int, int, off_t) __INTRODUCED_IN(24);
#endif
diff --git a/libc/include/bits/termios_inlines.h b/libc/include/bits/termios_inlines.h
new file mode 100644
index 0000000..d49167e
--- /dev/null
+++ b/libc/include/bits/termios_inlines.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef _BITS_TERMIOS_INLINES_H_
+#define _BITS_TERMIOS_INLINES_H_
+
+#include <errno.h>
+#include <sys/cdefs.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+#include <linux/termios.h>
+
+#if !defined(__BIONIC_TERMIOS_INLINE)
+#define __BIONIC_TERMIOS_INLINE static __inline
+#endif
+
+__BEGIN_DECLS
+
+static __inline speed_t cfgetspeed(const struct termios* s) {
+ return __BIONIC_CAST(static_cast, speed_t, s->c_cflag & CBAUD);
+}
+
+__BIONIC_TERMIOS_INLINE speed_t cfgetispeed(const struct termios* s) {
+ return cfgetspeed(s);
+}
+
+__BIONIC_TERMIOS_INLINE speed_t cfgetospeed(const struct termios* s) {
+ return cfgetspeed(s);
+}
+
+__BIONIC_TERMIOS_INLINE void cfmakeraw(struct termios* s) {
+ s->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+ s->c_oflag &= ~OPOST;
+ s->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+ s->c_cflag &= ~(CSIZE|PARENB);
+ s->c_cflag |= CS8;
+}
+
+__BIONIC_TERMIOS_INLINE int cfsetspeed(struct termios* s, speed_t speed) {
+ // TODO: check 'speed' is valid.
+ s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);
+ return 0;
+}
+
+__BIONIC_TERMIOS_INLINE int cfsetispeed(struct termios* s, speed_t speed) {
+ return cfsetspeed(s, speed);
+}
+
+__BIONIC_TERMIOS_INLINE int cfsetospeed(struct termios* s, speed_t speed) {
+ return cfsetspeed(s, speed);
+}
+
+__BIONIC_TERMIOS_INLINE int tcdrain(int fd) {
+ // A non-zero argument to TCSBRK means "don't send a break".
+ // The drain is a side-effect of the ioctl!
+ return ioctl(fd, TCSBRK, __BIONIC_CAST(static_cast, unsigned long, 1));
+}
+
+__BIONIC_TERMIOS_INLINE int tcflow(int fd, int action) {
+ return ioctl(fd, TCXONC, __BIONIC_CAST(static_cast, unsigned long, action));
+}
+
+__BIONIC_TERMIOS_INLINE int tcflush(int fd, int queue) {
+ return ioctl(fd, TCFLSH, __BIONIC_CAST(static_cast, unsigned long, queue));
+}
+
+__BIONIC_TERMIOS_INLINE int tcgetattr(int fd, struct termios* s) {
+ return ioctl(fd, TCGETS, s);
+}
+
+__BIONIC_TERMIOS_INLINE pid_t tcgetsid(int fd) {
+ pid_t sid;
+ return (ioctl(fd, TIOCGSID, &sid) == -1) ? -1 : sid;
+}
+
+__BIONIC_TERMIOS_INLINE int tcsendbreak(int fd, int duration) {
+ return ioctl(fd, TCSBRKP, __BIONIC_CAST(static_cast, unsigned long, duration));
+}
+
+__BIONIC_TERMIOS_INLINE int tcsetattr(int fd, int optional_actions, const struct termios* s) {
+ int cmd;
+ switch (optional_actions) {
+ case TCSANOW: cmd = TCSETS; break;
+ case TCSADRAIN: cmd = TCSETSW; break;
+ case TCSAFLUSH: cmd = TCSETSF; break;
+ default: errno = EINVAL; return -1;
+ }
+ return ioctl(fd, cmd, s);
+}
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/dirent.h b/libc/include/dirent.h
index 3f9ad18..ebcf085 100644
--- a/libc/include/dirent.h
+++ b/libc/include/dirent.h
@@ -31,6 +31,7 @@
#include <stdint.h>
#include <sys/cdefs.h>
+#include <sys/types.h>
__BEGIN_DECLS
@@ -46,17 +47,24 @@
#define DT_WHT 14
#endif
+#if defined(__LP64__)
+#define __DIRENT64_INO_T ino_t
+#else
+#define __DIRENT64_INO_T uint64_t /* Historical accident. */
+#endif
+
#define __DIRENT64_BODY \
- uint64_t d_ino; \
- int64_t d_off; \
- unsigned short d_reclen; \
- unsigned char d_type; \
- char d_name[256]; \
+ __DIRENT64_INO_T d_ino; \
+ off64_t d_off; \
+ unsigned short d_reclen; \
+ unsigned char d_type; \
+ char d_name[256]; \
struct dirent { __DIRENT64_BODY };
struct dirent64 { __DIRENT64_BODY };
#undef __DIRENT64_BODY
+#undef __DIRENT64_INO_T
/* glibc compatibility. */
#undef _DIRENT_HAVE_D_NAMLEN /* Linux doesn't have a d_namlen field. */
diff --git a/libc/include/dlfcn.h b/libc/include/dlfcn.h
index b8f3cec..018482d 100644
--- a/libc/include/dlfcn.h
+++ b/libc/include/dlfcn.h
@@ -57,23 +57,20 @@
void* dlvsym(void* handle, const char* _Nonnull symbol, const char* _Nonnull version) __INTRODUCED_IN(24);
int dladdr(const void* addr, Dl_info* _Nonnull info);
-enum {
-#if defined(__LP64__)
- RTLD_NOW = 2,
-#else
- RTLD_NOW = 0,
-#endif
- RTLD_LAZY = 1,
+#define RTLD_LOCAL 0
+#define RTLD_LAZY 0x00001
+#define RTLD_NOW 0x00002
+#define RTLD_NOLOAD 0x00004
+#define RTLD_GLOBAL 0x00100
+#define RTLD_NODELETE 0x01000
- RTLD_LOCAL = 0,
-#if defined(__LP64__)
- RTLD_GLOBAL = 0x00100,
-#else
- RTLD_GLOBAL = 2,
+#if !defined(__LP64__)
+/* LP32 is broken for historical reasons. */
+#undef RTLD_NOW
+#define RTLD_NOW 0x00000
+#undef RTLD_GLOBAL
+#define RTLD_GLOBAL 0x00002
#endif
- RTLD_NOLOAD = 4,
- RTLD_NODELETE = 0x01000,
-};
#if defined (__LP64__)
#define RTLD_DEFAULT __BIONIC_CAST(reinterpret_cast, void*, 0)
diff --git a/libc/include/errno.h b/libc/include/errno.h
index 3f4cff9..cbe67fa 100644
--- a/libc/include/errno.h
+++ b/libc/include/errno.h
@@ -25,6 +25,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+
#ifndef _ERRNO_H
#define _ERRNO_H
@@ -33,18 +34,13 @@
__BEGIN_DECLS
-/* on Linux, ENOTSUP and EOPNOTSUPP are defined as the same error code
- * even if 1000.3 states that they should be different
- */
-#ifndef ENOTSUP
-#define ENOTSUP EOPNOTSUPP
+/* On Linux, ENOTSUP and EOPNOTSUPP are the same despite POSIX saying they should be distinct. */
+#ifndef ENOTSUP
+#define ENOTSUP EOPNOTSUPP
#endif
-/* internal function returning the address of the thread-specific errno */
-volatile int* __errno(void) __attribute_const__;
-
-/* a macro expanding to the errno l-value */
-#define errno (*__errno())
+int* __errno(void) __attribute_const__;
+#define errno (*__errno())
__END_DECLS
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h
index 652430c..c98022c 100644
--- a/libc/include/fcntl.h
+++ b/libc/include/fcntl.h
@@ -56,14 +56,18 @@
#define O_ASYNC FASYNC
#define O_RSYNC O_SYNC
+#if __ANDROID_API__ >= __ANDROID_API_L__
#define SPLICE_F_MOVE 1
#define SPLICE_F_NONBLOCK 2
#define SPLICE_F_MORE 4
#define SPLICE_F_GIFT 8
+#endif
+#if __ANDROID_API__ >= __ANDROID_API_O__
#define SYNC_FILE_RANGE_WAIT_BEFORE 1
#define SYNC_FILE_RANGE_WRITE 2
#define SYNC_FILE_RANGE_WAIT_AFTER 4
+#endif
int creat(const char*, mode_t);
int creat64(const char*, mode_t) __INTRODUCED_IN(21);
diff --git a/libc/include/limits.h b/libc/include/limits.h
index a25eb65..157f7a6 100644
--- a/libc/include/limits.h
+++ b/libc/include/limits.h
@@ -138,9 +138,9 @@
#define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
-#define _POSIX_VERSION 200809L /* Posix C language bindings version */
-#define _POSIX2_VERSION -1 /* we don't support Posix command-line tools */
-#define _XOPEN_VERSION 700 /* by Posix definition */
+#define _POSIX_VERSION 200809L
+#define _POSIX2_VERSION _POSIX_VERSION
+#define _XOPEN_VERSION 700 /* by Posix definition */
/* >= _POSIX_THREAD_DESTRUCTOR_ITERATIONS */
#define PTHREAD_DESTRUCTOR_ITERATIONS 4
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index c34d1a3..7dec3cc 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -160,6 +160,26 @@
int pthread_mutex_trylock(pthread_mutex_t* _Nonnull);
int pthread_mutex_unlock(pthread_mutex_t* _Nonnull);
+#if defined(__LP32__) && __ANDROID_API__ < 21
+/*
+ * Cruft for supporting old API levels. Pre-L we didn't have the proper POSIX
+ * APIs for things, but instead had some locally grown, artisan equivalents.
+ * Keep exposing the old prototypes on old API levels so we don't regress
+ * functionality.
+ *
+ * See the following bugs:
+ * * https://github.com/android-ndk/ndk/issues/420
+ * * https://github.com/android-ndk/ndk/issues/423
+ * * https://stackoverflow.com/q/44580542/632035
+ */
+
+int pthread_mutex_lock_timeout_np(pthread_mutex_t* mutex, unsigned msecs);
+int pthread_cond_timeout_np(pthread_cond_t* cond, pthread_mutex_t* mutex, unsigned msecs);
+int pthread_cond_timedwait_monotonic_np(pthread_cond_t*, pthread_mutex_t*, const struct timespec*);
+int pthread_cond_timedwait_relative_np(pthread_cond_t* cond, pthread_mutex_t* mutex,
+ const struct timespec* reltime);
+#endif
+
int pthread_once(pthread_once_t* _Nonnull, void (* _Nonnull init_routine)(void));
int pthread_rwlockattr_init(pthread_rwlockattr_t* _Nonnull);
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index 24916d6..ca56437 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -176,17 +176,17 @@
int fseek(FILE*, long, int);
long ftell(FILE*);
-#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= __ANDROID_API_N__
-int fgetpos(FILE*, fpos_t*) __RENAME(fgetpos64);
-int fsetpos(FILE*, const fpos_t*) __RENAME(fsetpos64);
-int fseeko(FILE*, off_t, int) __RENAME(fseeko64);
-off_t ftello(FILE*) __RENAME(ftello64);
+#if defined(__USE_FILE_OFFSET64)
+int fgetpos(FILE*, fpos_t*) __RENAME(fgetpos64) __INTRODUCED_IN(24);
+int fsetpos(FILE*, const fpos_t*) __RENAME(fsetpos64) __INTRODUCED_IN(24);
+int fseeko(FILE*, off_t, int) __RENAME(fseeko64) __INTRODUCED_IN(24);
+off_t ftello(FILE*) __RENAME(ftello64) __INTRODUCED_IN(24);
# if defined(__USE_BSD)
FILE* funopen(const void*,
int (*)(void*, char*, int),
int (*)(void*, const char*, int),
fpos_t (*)(void*, fpos_t, int),
- int (*)(void*)) __RENAME(funopen64);
+ int (*)(void*)) __RENAME(funopen64) __INTRODUCED_IN(24);
# endif
#else
int fgetpos(FILE*, fpos_t*);
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/include/string.h b/libc/include/string.h
index c178a3c..c15fe4a 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -67,8 +67,8 @@
char* __strchr_chk(const char* _Nonnull, int, size_t) __INTRODUCED_IN(18);
#if defined(__USE_GNU)
#if defined(__cplusplus)
-extern "C++" char* strchrnul(char* _Nonnull, int) __RENAME(strchrnul) __attribute_pure__;
-extern "C++" const char* strchrnul(const char* _Nonnull, int) __RENAME(strchrnul) __attribute_pure__;
+extern "C++" char* strchrnul(char* _Nonnull, int) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
+extern "C++" const char* strchrnul(const char* _Nonnull, int) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
#else
char* strchrnul(const char* _Nonnull, int) __attribute_pure__ __INTRODUCED_IN(24);
#endif
@@ -142,8 +142,8 @@
* It doesn't modify its argument, and in C++ it's const-correct.
*/
#if defined(__cplusplus)
-extern "C++" char* basename(char* _Nonnull) __RENAME(__gnu_basename);
-extern "C++" const char* basename(const char* _Nonnull) __RENAME(__gnu_basename);
+extern "C++" char* basename(char* _Nonnull) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+extern "C++" const char* basename(const char* _Nonnull) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
#else
char* basename(const char* _Nonnull) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
#endif
diff --git a/libc/include/strings.h b/libc/include/strings.h
index 021e2b4..11f3213 100644
--- a/libc/include/strings.h
+++ b/libc/include/strings.h
@@ -54,8 +54,12 @@
#define bzero(b, len) (void)(__builtin_memset((b), '\0', (len)))
#endif
+#if !defined(__i386__) || __ANDROID_API__ >= __ANDROID_API_J_MR2__
int ffs(int) __INTRODUCED_IN_X86(18);
+#endif
__END_DECLS
+#include <android/legacy_strings_inlines.h>
+
#endif /* !defined(_STRINGS_H_) */
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 004c6b5..307545c 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -235,10 +235,11 @@
#endif
/* _FILE_OFFSET_BITS 64 support. */
-#if !defined(__LP64__) && defined(_FILE_OFFSET_BITS)
-#if _FILE_OFFSET_BITS == 64
+#if !defined(__LP64__) && defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64
#define __USE_FILE_OFFSET64 1
-#endif
+#define __RENAME_IF_FILE_OFFSET64(func) __RENAME(func)
+#else
+#define __RENAME_IF_FILE_OFFSET64(func)
#endif
#define __BIONIC__ 1
@@ -303,13 +304,23 @@
#define __pass_object_size __pass_object_size_n(__bos_level)
#define __pass_object_size0 __pass_object_size_n(0)
-/* Used to support clangisms with FORTIFY. This isn't in the FORTIFY section
- * because these change how symbols are emitted. The linker must be kept happy.
+/*
+ * Used to support clangisms with FORTIFY. Because these change how symbols are
+ * emitted, we need to ensure that bionic itself is built fortified. But lots
+ * of external code (especially stuff using configure) likes to declare
+ * functions directly, and they can't know that the overloadable attribute
+ * exists. This leads to errors like:
+ *
+ * dcigettext.c:151:7: error: redeclaration of 'getcwd' must have the 'overloadable' attribute
+ * char *getcwd ();
+ * ^
+ *
+ * To avoid this and keep such software building, don't use overloadable if
+ * we're not using fortify.
*/
-#ifdef __clang__
+#if defined(__clang__) && defined(__BIONIC_FORTIFY)
# define __overloadable __attribute__((overloadable))
-// Don't use __RENAME directly because on gcc, this could result in a number of
-// unnecessary renames.
+/* We don't use __RENAME directly because on gcc this could result in unnecessary renames. */
# define __RENAME_CLANG(x) __RENAME(x)
#else
# define __overloadable
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 9a2ec35..1440dc6 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -43,7 +43,7 @@
#define MREMAP_MAYMOVE 1
#define MREMAP_FIXED 2
-#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= __ANDROID_API_L__
+#if defined(__USE_FILE_OFFSET64)
void* mmap(void*, size_t, int, int, int, off_t) __RENAME(mmap64) __INTRODUCED_IN(21);
#else
void* mmap(void*, size_t, int, int, int, off_t);
@@ -71,7 +71,7 @@
* Some third-party code uses the existence of POSIX_MADV_NORMAL to detect the
* availability of posix_madvise. This is not correct, since having up-to-date
* UAPI headers says nothing about the C library, but for the time being we
- * don't want to harm adoption to the unified headers.
+ * don't want to harm adoption of the unified headers.
*
* https://github.com/android-ndk/ndk/issues/395
*/
diff --git a/libc/include/sys/mtio.h b/libc/include/sys/mtio.h
new file mode 100644
index 0000000..8fb5655
--- /dev/null
+++ b/libc/include/sys/mtio.h
@@ -0,0 +1 @@
+#include <linux/mtio.h>
diff --git a/libc/include/sys/procfs.h b/libc/include/sys/procfs.h
index 7ef5023..eff39e2 100644
--- a/libc/include/sys/procfs.h
+++ b/libc/include/sys/procfs.h
@@ -49,6 +49,14 @@
typedef pid_t lwpid_t;
typedef void* psaddr_t;
+struct elf_siginfo {
+ int si_signo;
+ int si_code;
+ int si_errno;
+};
+
+#define ELF_PRARGSZ 80
+
__END_DECLS
#endif /* _SYS_PROCFS_H_ */
diff --git a/libc/include/sys/sendfile.h b/libc/include/sys/sendfile.h
index dccdec5..43b334c 100644
--- a/libc/include/sys/sendfile.h
+++ b/libc/include/sys/sendfile.h
@@ -34,9 +34,8 @@
__BEGIN_DECLS
-#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= __ANDROID_API_L__
-ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) __RENAME(sendfile64)
- __INTRODUCED_IN(21);
+#if defined(__USE_FILE_OFFSET64)
+ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) __RENAME(sendfile64) __INTRODUCED_IN(21);
#else
ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count);
#endif
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index f8d854d..47ff5c4 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -127,6 +127,10 @@
#define st_atimensec st_atim.tv_nsec
#define st_mtimensec st_mtim.tv_nsec
#define st_ctimensec st_ctim.tv_nsec
+/* Compatibility with Linux headers and old NDKs. */
+#define st_atime_nsec st_atim.tv_nsec
+#define st_mtime_nsec st_mtim.tv_nsec
+#define st_ctime_nsec st_ctim.tv_nsec
#if defined(__USE_BSD)
/* Permission macros provided by glibc for compatibility with BSDs. */
diff --git a/libc/include/sys/ttydefaults.h b/libc/include/sys/ttydefaults.h
index 62af84b..4dcc649 100644
--- a/libc/include/sys/ttydefaults.h
+++ b/libc/include/sys/ttydefaults.h
@@ -48,7 +48,7 @@
* Defaults on "first" open.
*/
#define TTYDEF_IFLAG (BRKINT | ICRNL | IMAXBEL | IXON | IXANY)
-#define TTYDEF_OFLAG (OPOST | ONLCR | OXTABS)
+#define TTYDEF_OFLAG (OPOST | ONLCR | XTABS)
#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL)
#define TTYDEF_CFLAG (CREAD | CS8 | HUPCL)
#define TTYDEF_SPEED (B9600)
@@ -58,7 +58,7 @@
*/
#define CTRL(x) (x&037)
#define CEOF CTRL('d')
-#define CEOL ((unsigned char)'\377') /* XXX avoid _POSIX_VDISABLE */
+#define CEOL '\0' /* XXX avoid _POSIX_VDISABLE */
#define CERASE 0177
#define CINTR CTRL('c')
#define CSTATUS CTRL('t')
@@ -80,34 +80,4 @@
#define CRPRNT CREPRINT
#define CFLUSH CDISCARD
-/* PROTECTED INCLUSION ENDS HERE */
#endif /* !_SYS_TTYDEFAULTS_H_ */
-
-/*
- * #define TTYDEFCHARS to include an array of default control characters.
- */
-#ifdef TTYDEFCHARS
-const cc_t ttydefchars[NCCS] = {
- [VEOF] = CEOF,
- [VEOL] = CEOL,
- [VEOL2] = CEOL,
- [VERASE] = CERASE,
- [VWERASE] = CWERASE,
- [VKILL] = CKILL,
- [VREPRINT] = CREPRINT,
- [7] = _POSIX_VDISABLE, /* spare */
- [VINTR] = CINTR,
- [VQUIT] = CQUIT,
- [VSUSP] = CSUSP,
- [VDSUSP] = CDSUSP,
- [VSTART] = CSTART,
- [VSTOP] = CSTOP,
- [VLNEXT] = CLNEXT,
- [VDISCARD] = CDISCARD,
- [VMIN] = CMIN,
- [VTIME] = CTIME,
- [VSTATUS] = CSTATUS,
- [19] = _POSIX_VDISABLE, /* spare */
-};
-#undef TTYDEFCHARS
-#endif
diff --git a/libc/include/sys/ucontext.h b/libc/include/sys/ucontext.h
index 4eddf23..4cc66eb 100644
--- a/libc/include/sys/ucontext.h
+++ b/libc/include/sys/ucontext.h
@@ -40,21 +40,37 @@
enum {
REG_R0 = 0,
+#define REG_R0 REG_R0
REG_R1,
+#define REG_R1 REG_R1
REG_R2,
+#define REG_R2 REG_R2
REG_R3,
+#define REG_R3 REG_R3
REG_R4,
+#define REG_R4 REG_R4
REG_R5,
+#define REG_R5 REG_R5
REG_R6,
+#define REG_R6 REG_R6
REG_R7,
+#define REG_R7 REG_R7
REG_R8,
+#define REG_R8 REG_R8
REG_R9,
+#define REG_R9 REG_R9
REG_R10,
+#define REG_R10 REG_R10
REG_R11,
+#define REG_R11 REG_R11
REG_R12,
+#define REG_R12 REG_R12
REG_R13,
+#define REG_R13 REG_R13
REG_R14,
+#define REG_R14 REG_R14
REG_R15,
+#define REG_R15 REG_R15
};
#define NGREG 18 /* Like glibc. */
@@ -103,25 +119,45 @@
enum {
REG_GS = 0,
+#define REG_GS REG_GS
REG_FS,
+#define REG_FS REG_FS
REG_ES,
+#define REG_ES REG_ES
REG_DS,
+#define REG_DS REG_DS
REG_EDI,
+#define REG_EDI REG_EDI
REG_ESI,
+#define REG_ESI REG_ESI
REG_EBP,
+#define REG_EBP REG_EBP
REG_ESP,
+#define REG_ESP REG_ESP
REG_EBX,
+#define REG_EBX REG_EBX
REG_EDX,
+#define REG_EDX REG_EDX
REG_ECX,
+#define REG_ECX REG_ECX
REG_EAX,
+#define REG_EAX REG_EAX
REG_TRAPNO,
+#define REG_TRAPNO REG_TRAPNO
REG_ERR,
+#define REG_ERR REG_ERR
REG_EIP,
+#define REG_EIP REG_EIP
REG_CS,
+#define REG_CS REG_CS
REG_EFL,
+#define REG_EFL REG_EFL
REG_UESP,
+#define REG_UESP REG_UESP
REG_SS,
+#define REG_SS REG_SS
NGREG
+#define NGREG NGREG
};
typedef int greg_t;
@@ -237,29 +273,53 @@
enum {
REG_R8 = 0,
+#define REG_R8 REG_R8
REG_R9,
+#define REG_R9 REG_R9
REG_R10,
+#define REG_R10 REG_R10
REG_R11,
+#define REG_R11 REG_R11
REG_R12,
+#define REG_R12 REG_R12
REG_R13,
+#define REG_R13 REG_R13
REG_R14,
+#define REG_R14 REG_R14
REG_R15,
+#define REG_R15 REG_R15
REG_RDI,
+#define REG_RDI REG_RDI
REG_RSI,
+#define REG_RSI REG_RSI
REG_RBP,
+#define REG_RBP REG_RBP
REG_RBX,
+#define REG_RBX REG_RBX
REG_RDX,
+#define REG_RDX REG_RDX
REG_RAX,
+#define REG_RAX REG_RAX
REG_RCX,
+#define REG_RCX REG_RCX
REG_RSP,
+#define REG_RSP REG_RSP
REG_RIP,
+#define REG_RIP REG_RIP
REG_EFL,
+#define REG_EFL REG_EFL
REG_CSGSFS,
+#define REG_CSGSFS REG_CSGSFS
REG_ERR,
+#define REG_ERR REG_ERR
REG_TRAPNO,
+#define REG_TRAPNO REG_TRAPNO
REG_OLDMASK,
+#define REG_OLDMASK REG_OLDMASK
REG_CR2,
+#define REG_CR2 REG_CR2
NGREG
+#define NGREG NGREG
};
typedef long greg_t;
diff --git a/libc/include/sys/uio.h b/libc/include/sys/uio.h
index 0e56d7d..2611774 100644
--- a/libc/include/sys/uio.h
+++ b/libc/include/sys/uio.h
@@ -39,8 +39,8 @@
#if defined(__USE_GNU)
#if defined(__USE_FILE_OFFSET64)
-ssize_t preadv(int, const struct iovec*, int, off_t) __RENAME(preadv64);
-ssize_t pwritev(int, const struct iovec*, int, off_t) __RENAME(pwritev64);
+ssize_t preadv(int, const struct iovec*, int, off_t) __RENAME(preadv64) __INTRODUCED_IN(24);
+ssize_t pwritev(int, const struct iovec*, int, off_t) __RENAME(pwritev64) __INTRODUCED_IN(24);
#else
ssize_t preadv(int, const struct iovec*, int, off_t) __INTRODUCED_IN(24);
ssize_t pwritev(int, const struct iovec*, int, off_t) __INTRODUCED_IN(24);
diff --git a/libc/include/sys/user.h b/libc/include/sys/user.h
index f9ad956..ed3e10a 100644
--- a/libc/include/sys/user.h
+++ b/libc/include/sys/user.h
@@ -102,6 +102,10 @@
int u_debugreg[8];
};
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * PAGE_SIZE)
+
#elif defined(__x86_64__)
struct user_fpregs_struct {
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index ff2e9f6..e024527 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -173,7 +173,7 @@
off64_t lseek64(int __fd, off64_t __offset, int __whence);
-#if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= __ANDROID_API_L__
+#if defined(__USE_FILE_OFFSET64)
int truncate(const char* __path, off_t __length) __RENAME(truncate64) __INTRODUCED_IN(21);
ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset)
__overloadable __RENAME(pread64) __INTRODUCED_IN(12);
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index d3e9f5c..c9a78be 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -42,23 +42,6 @@
__BEGIN_DECLS
-enum {
- WC_TYPE_INVALID = 0,
- WC_TYPE_ALNUM,
- WC_TYPE_ALPHA,
- WC_TYPE_BLANK,
- WC_TYPE_CNTRL,
- WC_TYPE_DIGIT,
- WC_TYPE_GRAPH,
- WC_TYPE_LOWER,
- WC_TYPE_PRINT,
- WC_TYPE_PUNCT,
- WC_TYPE_SPACE,
- WC_TYPE_UPPER,
- WC_TYPE_XDIGIT,
- WC_TYPE_MAX
-};
-
wint_t btowc(int);
int fwprintf(FILE *, const wchar_t *, ...);
int fwscanf(FILE *, const wchar_t *, ...);
diff --git a/libc/private/bionic_mbstate.h b/libc/private/bionic_mbstate.h
index 018b47c..292959a 100644
--- a/libc/private/bionic_mbstate.h
+++ b/libc/private/bionic_mbstate.h
@@ -43,11 +43,31 @@
#define __MB_IS_ERR(rv) (rv == __MB_ERR_ILLEGAL_SEQUENCE || \
rv == __MB_ERR_INCOMPLETE_SEQUENCE)
-size_t mbstate_bytes_so_far(const mbstate_t* ps);
-void mbstate_set_byte(mbstate_t* ps, int i, char byte);
-uint8_t mbstate_get_byte(const mbstate_t* ps, int n);
-size_t reset_and_return_illegal(int _errno, mbstate_t* ps);
-size_t reset_and_return(int _return, mbstate_t* ps);
+static inline __wur size_t mbstate_bytes_so_far(const mbstate_t* ps) {
+ return
+ (ps->__seq[2] != 0) ? 3 :
+ (ps->__seq[1] != 0) ? 2 :
+ (ps->__seq[0] != 0) ? 1 : 0;
+}
+
+static inline void mbstate_set_byte(mbstate_t* ps, int i, char byte) {
+ ps->__seq[i] = static_cast<uint8_t>(byte);
+}
+
+static inline __wur uint8_t mbstate_get_byte(const mbstate_t* ps, int n) {
+ return ps->__seq[n];
+}
+
+static inline __wur size_t mbstate_reset_and_return_illegal(int _errno, mbstate_t* ps) {
+ errno = _errno;
+ *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
+ return __MB_ERR_ILLEGAL_SEQUENCE;
+}
+
+static inline __wur size_t mbstate_reset_and_return(int _return, mbstate_t* ps) {
+ *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
+ return _return;
+}
__END_DECLS
diff --git a/libc/tools/generate-NOTICE.py b/libc/tools/generate-NOTICE.py
index 6573644..d40891c 100755
--- a/libc/tools/generate-NOTICE.py
+++ b/libc/tools/generate-NOTICE.py
@@ -14,17 +14,33 @@
import tarfile
import tempfile
-def IsUninteresting(path):
- path = path.lower()
- if path.endswith(".mk") or path.endswith(".py") or path.endswith(".pyc") or path.endswith(".txt") or path.endswith(".3") or path.endswith(".swp"):
- return True
- if path.endswith("/notice") or path.endswith("/readme") or path.endswith("/caveats"):
- return True
- if path.endswith("/tzdata") or path.endswith("/zoneinfo/generate"):
- return True
- return False
+VERBOSE = False
-def IsAutoGenerated(content):
+def warn(s):
+ sys.stderr.write("warning: %s\n" % s)
+
+def warn_verbose(s):
+ if VERBOSE:
+ warn(s)
+
+def is_interesting(path):
+ path = path.lower()
+ uninteresting_extensions = [
+ ".bp",
+ ".map",
+ ".mk",
+ ".py",
+ ".pyc",
+ ".swp",
+ ".txt",
+ ]
+ if os.path.splitext(path)[1] in uninteresting_extensions:
+ return False
+ if path.endswith("/notice") or path.endswith("/readme"):
+ return False
+ return True
+
+def is_auto_generated(content):
if "Generated by gensyscalls.py" in content or "generated by genserv.py" in content:
return True
if "This header was automatically generated from a Linux kernel header" in content:
@@ -33,7 +49,7 @@
copyrights = set()
-def ExtractCopyrightAt(lines, i):
+def extract_copyright_at(lines, i):
hash = lines[i].startswith("#")
# Do we need to back up to find the start of the copyright header?
@@ -100,13 +116,42 @@
return i
-args = sys.argv[1:]
-if len(args) == 0:
- args = [ "." ]
-for arg in args:
- sys.stderr.write('Searching for source files in "%s"...\n' % arg)
+def do_file(path):
+ with open(path, "r") as the_file:
+ try:
+ content = open(path, "r").read().decode("utf-8")
+ except UnicodeDecodeError:
+ warn("bad UTF-8 in %s" % path)
+ content = open(path, "r").read().decode("iso-8859-1")
+ lines = content.split("\n")
+
+ if len(lines) <= 4:
+ warn_verbose("ignoring short file %s" % path)
+ return
+
+ if is_auto_generated(content):
+ warn_verbose("ignoring auto-generated file %s" % path)
+ return
+
+ if not "Copyright" in content:
+ if "public domain" in content.lower():
+ warn("ignoring public domain file %s" % path)
+ return
+ warn('no copyright notice found in "%s" (%d lines)' % (path, len(lines)))
+ return
+
+ # Manually iterate because extract_copyright_at tells us how many lines to skip.
+ i = 0
+ while i < len(lines):
+ if "Copyright" in lines[i] and not "@(#) Copyright" in lines[i]:
+ i = extract_copyright_at(lines, i)
+ else:
+ i += 1
+
+
+def do_dir(path):
for directory, sub_directories, filenames in os.walk(arg):
if ".git" in sub_directories:
sub_directories.remove(".git")
@@ -114,45 +159,24 @@
for filename in sorted(filenames):
path = os.path.join(directory, filename)
- if IsUninteresting(path):
- #print "ignoring uninteresting file %s" % path
- continue
+ if is_interesting(path):
+ do_file(path)
- try:
- content = open(path, 'r').read().decode('utf-8')
- except:
- sys.stderr.write('warning: bad UTF-8 in %s\n' % path)
- content = open(path, 'r').read().decode('iso-8859-1')
- lines = content.split("\n")
+args = sys.argv[1:]
+if len(args) == 0:
+ args = [ "." ]
- if len(lines) <= 4:
- #print "ignoring short file %s" % path
- continue
-
- if IsAutoGenerated(content):
- #print "ignoring auto-generated file %s" % path
- continue
-
- if not "Copyright" in content:
- if "public domain" in content.lower():
- #print "ignoring public domain file %s" % path
- continue
- sys.stderr.write('warning: no copyright notice found in "%s" (%d lines)\n' % (path, len(lines)))
- continue
-
- i = 0
- while i < len(lines):
- if "Copyright" in lines[i] and not "@(#) Copyright" in lines[i]:
- i = ExtractCopyrightAt(lines, i)
- i += 1
-
- #print path
+for arg in args:
+ if os.path.isdir(arg):
+ do_dir(arg)
+ else:
+ do_file(arg)
for copyright in sorted(copyrights):
- print copyright.encode('utf-8')
+ print copyright.encode("utf-8")
print
- print '-------------------------------------------------------------------'
+ print "-------------------------------------------------------------------"
print
sys.exit(0)
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/qsort.c b/libc/upstream-freebsd/lib/libc/stdlib/qsort.c
index 93e22cd..1ccc518 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/qsort.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/qsort.c
@@ -41,47 +41,53 @@
typedef int cmp_t(const void *, const void *);
#endif
static inline char *med3(char *, char *, char *, cmp_t *, void *);
-static inline void swapfunc(char *, char *, int, int);
+static inline void swapfunc(char *, char *, size_t, int, int);
-#define min(a, b) (a) < (b) ? a : b
+#define MIN(a, b) ((a) < (b) ? a : b)
/*
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
*/
-#define swapcode(TYPE, parmi, parmj, n) { \
- long i = (n) / sizeof (TYPE); \
- TYPE *pi = (TYPE *) (parmi); \
- TYPE *pj = (TYPE *) (parmj); \
+#define swapcode(TYPE, parmi, parmj, n) { \
+ size_t i = (n) / sizeof (TYPE); \
+ TYPE *pi = (TYPE *) (parmi); \
+ TYPE *pj = (TYPE *) (parmj); \
do { \
TYPE t = *pi; \
*pi++ = *pj; \
*pj++ = t; \
- } while (--i > 0); \
+ } while (--i > 0); \
}
-#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
- es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
+#define SWAPINIT(TYPE, a, es) swaptype_ ## TYPE = \
+ ((char *)a - (char *)0) % sizeof(TYPE) || \
+ es % sizeof(TYPE) ? 2 : es == sizeof(TYPE) ? 0 : 1;
static inline void
-swapfunc(a, b, n, swaptype)
- char *a, *b;
- int n, swaptype;
+swapfunc(char *a, char *b, size_t n, int swaptype_long, int swaptype_int)
{
- if(swaptype <= 1)
+ if (swaptype_long <= 1)
swapcode(long, a, b, n)
+ else if (swaptype_int <= 1)
+ swapcode(int, a, b, n)
else
swapcode(char, a, b, n)
}
-#define swap(a, b) \
- if (swaptype == 0) { \
+#define swap(a, b) \
+ if (swaptype_long == 0) { \
long t = *(long *)(a); \
*(long *)(a) = *(long *)(b); \
*(long *)(b) = t; \
+ } else if (swaptype_int == 0) { \
+ int t = *(int *)(a); \
+ *(int *)(a) = *(int *)(b); \
+ *(int *)(b) = t; \
} else \
- swapfunc(a, b, es, swaptype)
+ swapfunc(a, b, es, swaptype_long, swaptype_int)
-#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
+#define vecswap(a, b, n) \
+ if ((n) > 0) swapfunc(a, b, n, swaptype_long, swaptype_int)
#ifdef I_AM_QSORT_R
#define CMP(t, x, y) (cmp((t), (x), (y)))
@@ -98,24 +104,25 @@
{
return CMP(thunk, a, b) < 0 ?
(CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a ))
- :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
+ :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
}
#ifdef I_AM_QSORT_R
void
qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
#else
-#define thunk NULL
+#define thunk NULL
void
qsort(void *a, size_t n, size_t es, cmp_t *cmp)
#endif
{
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
- size_t d, r;
+ size_t d1, d2;
int cmp_result;
- int swaptype, swap_cnt;
+ int swaptype_long, swaptype_int, swap_cnt;
-loop: SWAPINIT(a, es);
+loop: SWAPINIT(long, a, es);
+ SWAPINIT(int, a, es);
swap_cnt = 0;
if (n < 7) {
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
@@ -130,7 +137,8 @@
pl = a;
pn = (char *)a + (n - 1) * es;
if (n > 40) {
- d = (n / 8) * es;
+ size_t d = (n / 8) * es;
+
pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk);
pm = med3(pm - d, pm, pm + d, cmp, thunk);
pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk);
@@ -175,21 +183,43 @@
}
pn = (char *)a + n * es;
- r = min(pa - (char *)a, pb - pa);
- vecswap(a, pb - r, r);
- r = min(pd - pc, pn - pd - es);
- vecswap(pb, pn - r, r);
- if ((r = pb - pa) > es)
+ d1 = MIN(pa - (char *)a, pb - pa);
+ vecswap(a, pb - d1, d1);
+ d1 = MIN(pd - pc, pn - pd - es);
+ vecswap(pb, pn - d1, d1);
+
+ d1 = pb - pa;
+ d2 = pd - pc;
+ if (d1 <= d2) {
+ /* Recurse on left partition, then iterate on right partition */
+ if (d1 > es) {
#ifdef I_AM_QSORT_R
- qsort_r(a, r / es, es, thunk, cmp);
+ qsort_r(a, d1 / es, es, thunk, cmp);
#else
- qsort(a, r / es, es, cmp);
+ qsort(a, d1 / es, es, cmp);
#endif
- if ((r = pd - pc) > es) {
- /* Iterate rather than recurse to save stack space */
- a = pn - r;
- n = r / es;
- goto loop;
+ }
+ if (d2 > es) {
+ /* Iterate rather than recurse to save stack space */
+ /* qsort(pn - d2, d2 / es, es, cmp); */
+ a = pn - d2;
+ n = d2 / es;
+ goto loop;
+ }
+ } else {
+ /* Recurse on right partition, then iterate on left partition */
+ if (d2 > es) {
+#ifdef I_AM_QSORT_R
+ qsort_r(pn - d2, d2 / es, es, thunk, cmp);
+#else
+ qsort(pn - d2, d2 / es, es, cmp);
+#endif
+ }
+ if (d1 > es) {
+ /* Iterate rather than recurse to save stack space */
+ /* qsort(a, d1 / es, es, cmp); */
+ n = d1 / es;
+ goto loop;
+ }
}
-/* qsort(pn - r, r / es, es, cmp);*/
}
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/libc/zoneinfo/Android.mk b/libc/zoneinfo/Android.mk
deleted file mode 100644
index faa1f06..0000000
--- a/libc/zoneinfo/Android.mk
+++ /dev/null
@@ -1,46 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := tzdata
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/usr/share/zoneinfo
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := tzlookup.xml
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/usr/share/zoneinfo
-include $(BUILD_PREBUILT)
-
-# The host build doesn't use bionic, but it does use bionic's zoneinfo data
-ifeq ($(WITH_HOST_DALVIK),true)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := tzdata-host
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-LOCAL_IS_HOST_MODULE := true
-LOCAL_SRC_FILES := tzdata
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_STEM := $(LOCAL_SRC_FILES)
-LOCAL_MODULE_PATH := $(HOST_OUT)/usr/share/zoneinfo
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := tzlookup.xml-host
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-LOCAL_IS_HOST_MODULE := true
-LOCAL_SRC_FILES := tzlookup.xml
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_STEM := $(LOCAL_SRC_FILES)
-LOCAL_MODULE_PATH := $(HOST_OUT)/usr/share/zoneinfo
-include $(BUILD_PREBUILT)
-
-endif
diff --git a/libc/zoneinfo/MODULE_LICENSE_PUBLIC_DOMAIN b/libc/zoneinfo/MODULE_LICENSE_PUBLIC_DOMAIN
deleted file mode 100644
index e69de29..0000000
--- a/libc/zoneinfo/MODULE_LICENSE_PUBLIC_DOMAIN
+++ /dev/null
diff --git a/libc/zoneinfo/tzdata b/libc/zoneinfo/tzdata
deleted file mode 100644
index c5932bc..0000000
--- a/libc/zoneinfo/tzdata
+++ /dev/null
Binary files differ
diff --git a/libc/zoneinfo/tzlookup.xml b/libc/zoneinfo/tzlookup.xml
deleted file mode 100644
index 5846f50..0000000
--- a/libc/zoneinfo/tzlookup.xml
+++ /dev/null
@@ -1,1622 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<timezones>
- <!-- Time zones by country.
-
- Data in this file originates from IANA's zone.tab file.
- The ordering of zones within each country is Android-specific and
- affects Android behavior, see below for details.
-
- The ordering of country elements is not important but is kept in ASCII
- order by code for easier maintenance. There must only be one country
- element per unique code. The code attribute is the (lower cased)
- ISO 3166 2-character country code used in the IANA zones.tab file.
-
- The <id> entries contain the IANA IDs for time zones used in a
- country.
-
- The file is used when picking a time zone for an Android device given
- a known local time, offset from UTC and whether the local zone is
- currently observing DST.
-
- The ordering of <id> elements is important because it influence the
- order that time zones in a country are considered.
-
- Currently the <id> entries are mostly primarily ordered by raw (non-DST)
- offset and then "desirability". This ordering is an historical artifact
- that is likely to change in future.
-
- The most sensible ordering for <id> entries for a country is by
- population of users that observe the time zone to maximize the
- probability of matching an arbitrary user. Then:
-
- The first <id> entry for a given country should have the highest
- likelihood of matching the user's needs when only the user's country
- code is available.
-
- The first zone that matches a user's country, offset and DST state
- should have the highest likelihood of matching the user's needs when
- country code, offset and DST state are available.
- -->
- <countryzones>
-
- <!-- ANDORRA, 1:00 -->
- <country code="ad">
- <id>Europe/Andorra</id>
- </country>
-
- <!-- UNITED ARAB EMIRATES, 4:00 -->
- <country code="ae">
- <id>Asia/Dubai</id>
- </country>
-
- <!-- AFGHANISTAN, 4:30 -->
- <country code="af">
- <id>Asia/Kabul</id>
- </country>
-
- <!-- ANTIGUA AND BARBUDA, -4:00 -->
- <country code="ag">
- <id>America/Antigua</id>
- </country>
-
- <!-- ANGUILLA, -4:00 -->
- <country code="ai">
- <id>America/Anguilla</id>
- </country>
-
- <!-- ALBANIA, 1:00 -->
- <country code="al">
- <id>Europe/Tirane</id>
- </country>
-
- <!-- ARMENIA, 4:00 -->
- <country code="am">
- <id>Asia/Yerevan</id>
- </country>
-
- <!-- ANGOLA, 1:00 -->
- <country code="ao">
- <id>Africa/Luanda</id>
- </country>
-
- <!-- ANTARCTICA -->
- <country code="aq">
- <!-- 12:00 -->
- <id>Antarctica/McMurdo</id>
-
- <!-- 10:00 -->
- <id>Antarctica/DumontDUrville</id>
-
- <!-- 8:00 -->
- <id>Antarctica/Casey</id>
-
- <!-- 7:00 -->
- <id>Antarctica/Davis</id>
-
- <!-- 5:00 -->
- <id>Antarctica/Mawson</id>
-
- <!-- 6:00 -->
- <id>Antarctica/Vostok</id>
-
- <!-- 3:00 -->
- <id>Antarctica/Syowa</id>
-
- <!-- 0:00 -->
- <id>Antarctica/Troll</id>
-
- <!-- -3:00 -->
- <id>Antarctica/Rothera</id>
-
- <!-- -4:00 -->
- <id>Antarctica/Palmer</id>
- </country>
-
- <!-- ARGENTINA, -3:00 -->
- <country code="ar">
- <id>America/Argentina/Buenos_Aires</id>
- <id>America/Argentina/Cordoba</id>
- <id>America/Argentina/Salta</id>
- <id>America/Argentina/Jujuy</id>
- <id>America/Argentina/Tucuman</id>
- <id>America/Argentina/Catamarca</id>
- <id>America/Argentina/La_Rioja</id>
- <id>America/Argentina/San_Juan</id>
- <id>America/Argentina/Mendoza</id>
- <id>America/Argentina/San_Luis</id>
- <id>America/Argentina/Rio_Gallegos</id>
- <id>America/Argentina/Ushuaia</id>
- </country>
-
- <!-- AMERICAN SAMOA, -11:00 -->
- <country code="as">
- <id>Pacific/Pago_Pago</id>
- </country>
-
- <!-- AUSTRIA, 1:00 -->
- <country code="at">
- <id>Europe/Vienna</id>
- </country>
-
- <!-- AUSTRALIA -->
- <country code="au">
- <!-- 10:00 -->
- <id>Australia/Sydney</id>
- <id>Australia/Melbourne</id>
- <id>Australia/Brisbane</id>
- <id>Australia/Hobart</id>
- <id>Australia/Currie</id>
- <id>Australia/Lindeman</id>
-
- <!-- 11:00 -->
- <id>Antarctica/Macquarie</id>
-
- <!-- 10:30 -->
- <id>Australia/Lord_Howe</id>
-
- <!-- 9:30 -->
- <id>Australia/Adelaide</id>
- <id>Australia/Broken_Hill</id>
- <id>Australia/Darwin</id>
-
- <!-- 8:00 -->
- <id>Australia/Perth</id>
-
- <!-- 8:45 -->
- <id>Australia/Eucla</id>
- </country>
-
- <!-- ARUBA, -4:00 -->
- <country code="aw">
- <id>America/Aruba</id>
- </country>
-
- <!-- ALAND ISLANDS, 2:00 -->
- <country code="ax">
- <id>Europe/Mariehamn</id>
- </country>
-
- <!-- AZERBAIJAN, 4:00 -->
- <country code="az">
- <id>Asia/Baku</id>
- </country>
-
- <!-- BOSNIA AND HERZEGOVINA, 1:00 -->
- <country code="ba">
- <id>Europe/Sarajevo</id>
- </country>
-
- <!-- BARBADOS, -4:00 -->
- <country code="bb">
- <id>America/Barbados</id>
- </country>
-
- <!-- BANGLADESH, 6:00 -->
- <country code="bd">
- <id>Asia/Dhaka</id>
- </country>
-
- <!-- BELGIUM, 1:00 -->
- <country code="be">
- <id>Europe/Brussels</id>
- </country>
-
- <!-- BURKINA FASO, 0:00 -->
- <country code="bf">
- <id>Africa/Ouagadougou</id>
- </country>
-
- <!-- BULGARIA, 2:00 -->
- <country code="bg">
- <id>Europe/Sofia</id>
- </country>
-
- <!-- BAHRAIN, 3:00 -->
- <country code="bh">
- <id>Asia/Bahrain</id>
- </country>
-
- <!-- BURUNDI, 2:00 -->
- <country code="bi">
- <id>Africa/Bujumbura</id>
- </country>
-
- <!-- BENIN, 1:00 -->
- <country code="bj">
- <id>Africa/Porto-Novo</id>
- </country>
-
- <!-- Saint Barthélemy, -4:00 -->
- <country code="bl">
- <id>America/St_Barthelemy</id>
- </country>
-
- <!-- BERMUDA, -4:00 -->
- <country code="bm">
- <id>Atlantic/Bermuda</id>
- </country>
-
- <!-- BRUNEI DARUSSALAM, 8:00 -->
- <country code="bn">
- <id>Asia/Brunei</id>
- </country>
-
- <!-- BOLIVIA, -4:00 -->
- <country code="bo">
- <id>America/La_Paz</id>
- </country>
-
- <!-- Caribbean Netherlands, -4:00 -->
- <country code="bq">
- <id>America/Kralendijk</id>
- </country>
-
- <!-- BRAZIL -->
- <country code="br">
- <!-- -2:00 -->
- <id>America/Noronha</id>
-
- <!-- -3:00 -->
- <id>America/Sao_Paulo</id>
- <id>America/Belem</id>
- <id>America/Fortaleza</id>
- <id>America/Recife</id>
- <id>America/Araguaina</id>
- <id>America/Maceio</id>
- <id>America/Bahia</id>
- <id>America/Santarem</id>
-
- <!-- -4:00 -->
- <id>America/Manaus</id>
- <id>America/Campo_Grande</id>
- <id>America/Cuiaba</id>
- <id>America/Porto_Velho</id>
- <id>America/Boa_Vista</id>
-
- <!-- -5:00 -->
- <id>America/Eirunepe</id>
- <id>America/Rio_Branco</id>
- </country>
-
- <!-- BAHAMAS, -5:00 -->
- <country code="bs">
- <id>America/Nassau</id>
- </country>
-
- <!-- BHUTAN, 6:00 -->
- <country code="bt">
- <id>Asia/Thimphu</id>
- </country>
-
- <!-- BOTSWANA, 2:00 -->
- <country code="bw">
- <id>Africa/Gaborone</id>
- </country>
-
- <!-- BELARUS, 3:00 -->
- <country code="by">
- <id>Europe/Minsk</id>
- </country>
-
- <!-- BELIZE, -6:00 -->
- <country code="bz">
- <id>America/Belize</id>
- </country>
-
- <!-- CANADA -->
- <country code="ca">
- <!-- -3:30 -->
- <id>America/St_Johns</id>
-
- <!-- -4:00 -->
- <id>America/Halifax</id>
- <id>America/Glace_Bay</id>
- <id>America/Moncton</id>
- <id>America/Goose_Bay</id>
- <id>America/Blanc-Sablon</id>
-
- <!-- -5:00 -->
- <id>America/Toronto</id>
- <id>America/Nipigon</id>
- <id>America/Thunder_Bay</id>
- <id>America/Iqaluit</id>
- <id>America/Pangnirtung</id>
- <id>America/Atikokan</id>
-
- <!-- -6:00 -->
- <id>America/Winnipeg</id>
- <id>America/Regina</id>
- <id>America/Rankin_Inlet</id>
- <id>America/Rainy_River</id>
- <id>America/Swift_Current</id>
- <id>America/Resolute</id>
-
- <!-- -7:00 -->
- <id>America/Edmonton</id>
- <id>America/Cambridge_Bay</id>
- <id>America/Yellowknife</id>
- <id>America/Inuvik</id>
- <id>America/Dawson_Creek</id>
- <id>America/Creston</id>
- <id>America/Fort_Nelson</id>
-
- <!-- -8:00 -->
- <id>America/Vancouver</id>
- <id>America/Whitehorse</id>
- <id>America/Dawson</id>
- </country>
-
- <!-- COCOS (KEELING) ISLANDS, 6:30 -->
- <country code="cc">
- <id>Indian/Cocos</id>
- </country>
-
- <!-- CONGO, THE DEMOCRATIC REPUBLIC OF THE -->
- <country code="cd">
- <!-- 2:00 -->
- <id>Africa/Lubumbashi</id>
-
- <!-- 1:00 -->
- <id>Africa/Kinshasa</id>
- </country>
-
- <!-- CENTRAL AFRICAN REPUBLIC, 1:00 -->
- <country code="cf">
- <id>Africa/Bangui</id>
- </country>
-
- <!-- CONGO, 1:00 -->
- <country code="cg">
- <id>Africa/Brazzaville</id>
- </country>
-
- <!-- SWITZERLAND, 1:00 -->
- <country code="ch">
- <id>Europe/Zurich</id>
- </country>
-
- <!-- COTE D'IVOIRE, 0:00 -->
- <country code="ci">
- <id>Africa/Abidjan</id>
- </country>
-
- <!-- COOK ISLANDS, -10:00 -->
- <country code="ck">
- <id>Pacific/Rarotonga</id>
- </country>
-
- <!-- CHILE -->
- <country code="cl">
- <!-- -3:00 -->
- <id>America/Punta_Arenas</id>
-
- <!-- -4:00 -->
- <id>America/Santiago</id>
-
- <!-- -6:00 -->
- <id>Pacific/Easter</id>
- </country>
-
- <!-- CAMEROON, 1:00 -->
- <country code="cm">
- <id>Africa/Douala</id>
- </country>
-
- <!-- CHINA -->
- <country code="cn">
- <!-- 8:00 -->
- <id>Asia/Shanghai</id>
-
- <!-- 6:00 -->
- <id>Asia/Urumqi</id>
- </country>
-
- <!-- COLOMBIA, -5:00 -->
- <country code="co">
- <id>America/Bogota</id>
- </country>
-
- <!-- COSTA RICA, -6:00 -->
- <country code="cr">
- <id>America/Costa_Rica</id>
- </country>
-
- <!-- CUBA, -5:00 -->
- <country code="cu">
- <id>America/Havana</id>
- </country>
-
- <!-- CAPE VERDE, -1:00 -->
- <country code="cv">
- <id>Atlantic/Cape_Verde</id>
- </country>
-
- <!-- Curaçao, -4:00 -->
- <country code="cw">
- <id>America/Curacao</id>
- </country>
-
- <!-- CHRISTMAS ISLAND, 7:00 -->
- <country code="cx">
- <id>Indian/Christmas</id>
- </country>
-
- <!-- CYPRUS -->
- <country code="cy">
- <!-- 2:00 -->
- <id>Asia/Nicosia</id>
-
- <!-- 3:00 -->
- <id>Asia/Famagusta</id>
- </country>
-
- <!-- CZECH REPUBLIC, 1:00 -->
- <country code="cz">
- <id>Europe/Prague</id>
- </country>
-
- <!-- GERMANY, 1:00 -->
- <country code="de">
- <id>Europe/Berlin</id>
- <id>Europe/Busingen</id>
- </country>
-
- <!-- DJIBOUTI, 3:00 -->
- <country code="dj">
- <id>Africa/Djibouti</id>
- </country>
-
- <!-- DENMARK, 1:00 -->
- <country code="dk">
- <id>Europe/Copenhagen</id>
- </country>
-
- <!-- DOMINICA, -4:00 -->
- <country code="dm">
- <id>America/Dominica</id>
- </country>
-
- <!-- DOMINICAN REPUBLIC, -4:00 -->
- <country code="do">
- <id>America/Santo_Domingo</id>
- </country>
-
- <!-- ALGERIA, 1:00 -->
- <country code="dz">
- <id>Africa/Algiers</id>
- </country>
-
- <!-- ECUADOR -->
- <country code="ec">
- <!-- -5:00 -->
- <id>America/Guayaquil</id>
-
- <!-- -6:00 -->
- <id>Pacific/Galapagos</id>
- </country>
-
- <!-- ESTONIA, 2:00 -->
- <country code="ee">
- <id>Europe/Tallinn</id>
- </country>
-
- <!-- EGYPT, 2:00 -->
- <country code="eg">
- <id>Africa/Cairo</id>
- </country>
-
- <!-- WESTERN SAHARA, 0:00 -->
- <country code="eh">
- <id>Africa/El_Aaiun</id>
- </country>
-
- <!-- ERITREA, 3:00 -->
- <country code="er">
- <id>Africa/Asmara</id>
- </country>
-
- <!-- SPAIN -->
- <country code="es">
- <!-- 1:00 -->
- <id>Europe/Madrid</id>
- <id>Africa/Ceuta</id>
-
- <!-- 0:00 -->
- <id>Atlantic/Canary</id>
- </country>
-
- <!-- ETHIOPIA, 3:00 -->
- <country code="et">
- <id>Africa/Addis_Ababa</id>
- </country>
-
- <!-- FINLAND, 2:00 -->
- <country code="fi">
- <id>Europe/Helsinki</id>
- </country>
-
- <!-- FIJI, 12:00 -->
- <country code="fj">
- <id>Pacific/Fiji</id>
- </country>
-
- <!-- FALKLAND ISLANDS (MALVINAS), -3:00 -->
- <country code="fk">
- <id>Atlantic/Stanley</id>
- </country>
-
- <!-- MICRONESIA, FEDERATED STATES OF -->
- <country code="fm">
- <!-- 11:00 -->
- <id>Pacific/Pohnpei</id>
- <id>Pacific/Kosrae</id>
-
- <!-- 10:00 -->
- <id>Pacific/Chuuk</id>
- </country>
-
- <!-- FAROE ISLANDS, 0:00 -->
- <country code="fo">
- <id>Atlantic/Faroe</id>
- </country>
-
- <!-- FRANCE, 1:00 -->
- <country code="fr">
- <id>Europe/Paris</id>
- </country>
-
- <!-- GABON, 1:00 -->
- <country code="ga">
- <id>Africa/Libreville</id>
- </country>
-
- <!-- UNITED KINGDOM, 0:00 -->
- <country code="gb">
- <id>Europe/London</id>
- </country>
-
- <!-- GRENADA, -4:00 -->
- <country code="gd">
- <id>America/Grenada</id>
- </country>
-
- <!-- GEORGIA, 4:00 -->
- <country code="ge">
- <id>Asia/Tbilisi</id>
- </country>
-
- <!-- FRENCH GUIANA, -3:00 -->
- <country code="gf">
- <id>America/Cayenne</id>
- </country>
-
- <!-- GUERNSEY, 0:00 -->
- <country code="gg">
- <id>Europe/Guernsey</id>
- </country>
-
- <!-- GHANA, 0:00 -->
- <country code="gh">
- <id>Africa/Accra</id>
- </country>
-
- <!-- GIBRALTAR, 1:00 -->
- <country code="gi">
- <id>Europe/Gibraltar</id>
- </country>
-
- <!-- GREENLAND -->
- <country code="gl">
- <!-- 0:00 -->
- <id>America/Danmarkshavn</id>
-
- <!-- -1:00 -->
- <id>America/Scoresbysund</id>
-
- <!-- -3:00 -->
- <id>America/Godthab</id>
-
- <!-- -4:00 -->
- <id>America/Thule</id>
- </country>
-
- <!-- GAMBIA, 0:00 -->
- <country code="gm">
- <id>Africa/Banjul</id>
- </country>
-
- <!-- GUINEA, 0:00 -->
- <country code="gn">
- <id>Africa/Conakry</id>
- </country>
-
- <!-- GUADELOUPE, -4:00 -->
- <country code="gp">
- <id>America/Guadeloupe</id>
- </country>
-
- <!-- EQUATORIAL GUINEA, 1:00 -->
- <country code="gq">
- <id>Africa/Malabo</id>
- </country>
-
- <!-- GREECE, 2:00 -->
- <country code="gr">
- <id>Europe/Athens</id>
- </country>
-
- <!-- SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS, -2:00 -->
- <country code="gs">
- <id>Atlantic/South_Georgia</id>
- </country>
-
- <!-- GUATEMALA, -6:00 -->
- <country code="gt">
- <id>America/Guatemala</id>
- </country>
-
- <!-- GUAM, 10:00 -->
- <country code="gu">
- <id>Pacific/Guam</id>
- </country>
-
- <!-- GUINEA-BISSAU, 0:00 -->
- <country code="gw">
- <id>Africa/Bissau</id>
- </country>
-
- <!-- GUYANA, -4:00 -->
- <country code="gy">
- <id>America/Guyana</id>
- </country>
-
- <!-- HONG KONG, 8:00 -->
- <country code="hk">
- <id>Asia/Hong_Kong</id>
- </country>
-
- <!-- HONDURAS, -6:00 -->
- <country code="hn">
- <id>America/Tegucigalpa</id>
- </country>
-
- <!-- CROATIA, 1:00 -->
- <country code="hr">
- <id>Europe/Zagreb</id>
- </country>
-
- <!-- HAITI, -5:00 -->
- <country code="ht">
- <id>America/Port-au-Prince</id>
- </country>
-
- <!-- HUNGARY, 1:00 -->
- <country code="hu">
- <id>Europe/Budapest</id>
- </country>
-
- <!-- INDONESIA -->
- <country code="id">
- <!-- 9:00 -->
- <id>Asia/Jayapura</id>
-
- <!-- 8:00 -->
- <id>Asia/Makassar</id>
-
- <!-- 7:00 -->
- <id>Asia/Jakarta</id>
- <id>Asia/Pontianak</id>
- </country>
-
- <!-- IRELAND, 0:00 -->
- <country code="ie">
- <id>Europe/Dublin</id>
- </country>
-
- <!-- ISRAEL, 2:00 -->
- <country code="il">
- <id>Asia/Jerusalem</id>
- </country>
-
- <!-- ISLE OF MAN, 0:00 -->
- <country code="im">
- <id>Europe/Isle_of_Man</id>
- </country>
-
- <!-- INDIA, 5:30 -->
- <country code="in">
- <id>Asia/Kolkata</id>
- </country>
-
- <!-- BRITISH INDIAN OCEAN TERRITORY, 6:00 -->
- <country code="io">
- <id>Indian/Chagos</id>
- </country>
-
- <!-- IRAQ, 3:00 -->
- <country code="iq">
- <id>Asia/Baghdad</id>
- </country>
-
- <!-- IRAN, ISLAMIC REPUBLIC OF, 3:30 -->
- <country code="ir">
- <id>Asia/Tehran</id>
- </country>
-
- <!-- ICELAND, 0:00 -->
- <country code="is">
- <id>Atlantic/Reykjavik</id>
- </country>
-
- <!-- ITALY, 1:00 -->
- <country code="it">
- <id>Europe/Rome</id>
- </country>
-
- <!-- JERSEY, 0:00 -->
- <country code="je">
- <id>Europe/Jersey</id>
- </country>
-
- <!-- JAMAICA, -5:00 -->
- <country code="jm">
- <id>America/Jamaica</id>
- </country>
-
- <!-- JORDAN, 2:00 -->
- <country code="jo">
- <id>Asia/Amman</id>
- </country>
-
- <!-- JAPAN, 9:00 -->
- <country code="jp">
- <id>Asia/Tokyo</id>
- </country>
-
- <!-- KENYA, 3:00 -->
- <country code="ke">
- <id>Africa/Nairobi</id>
- </country>
-
- <!-- KYRGYZSTAN, 6:00 -->
- <country code="kg">
- <id>Asia/Bishkek</id>
- </country>
-
- <!-- CAMBODIA, 7:00 -->
- <country code="kh">
- <id>Asia/Phnom_Penh</id>
- </country>
-
- <!-- KIRIBATI -->
- <country code="ki">
- <!-- 14:00 -->
- <id>Pacific/Kiritimati</id>
-
- <!-- 13:00 -->
- <id>Pacific/Enderbury</id>
-
- <!-- 12:00 -->
- <id>Pacific/Tarawa</id>
- </country>
-
- <!-- COMOROS, 3:00 -->
- <country code="km">
- <id>Indian/Comoro</id>
- </country>
-
- <!-- SAINT KITTS AND NEVIS, -4:00 -->
- <country code="kn">
- <id>America/St_Kitts</id>
- </country>
-
- <!-- KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF, 8:30 -->
- <country code="kp">
- <id>Asia/Pyongyang</id>
- </country>
-
- <!-- KOREA, REPUBLIC OF, 9:00 -->
- <country code="kr">
- <id>Asia/Seoul</id>
- </country>
-
- <!-- KUWAIT, 3:00 -->
- <country code="kw">
- <id>Asia/Kuwait</id>
- </country>
-
- <!-- CAYMAN ISLANDS, -5:00 -->
- <country code="ky">
- <id>America/Cayman</id>
- </country>
-
- <!-- KAZAKHSTAN -->
- <country code="kz">
- <!-- 6:00 -->
- <id>Asia/Almaty</id>
- <id>Asia/Qyzylorda</id>
-
- <!-- 5:00 -->
- <id>Asia/Aqtau</id>
- <id>Asia/Oral</id>
- <id>Asia/Aqtobe</id>
- <id>Asia/Atyrau</id>
- </country>
-
- <!-- LAO PEOPLE'S DEMOCRATIC REPUBLIC, 7:00 -->
- <country code="la">
- <id>Asia/Vientiane</id>
- </country>
-
- <!-- LEBANON, 2:00 -->
- <country code="lb">
- <id>Asia/Beirut</id>
- </country>
-
- <!-- SAINT LUCIA, -4:00 -->
- <country code="lc">
- <id>America/St_Lucia</id>
- </country>
-
- <!-- LIECHTENSTEIN, 1:00 -->
- <country code="li">
- <id>Europe/Vaduz</id>
- </country>
-
- <!-- SRI LANKA, 5:30 -->
- <country code="lk">
- <id>Asia/Colombo</id>
- </country>
-
- <!-- LIBERIA, 0:00 -->
- <country code="lr">
- <id>Africa/Monrovia</id>
- </country>
-
- <!-- LESOTHO, 2:00 -->
- <country code="ls">
- <id>Africa/Maseru</id>
- </country>
-
- <!-- LITHUANIA, 2:00 -->
- <country code="lt">
- <id>Europe/Vilnius</id>
- </country>
-
- <!-- LUXEMBOURG, 1:00 -->
- <country code="lu">
- <id>Europe/Luxembourg</id>
- </country>
-
- <!-- LATVIA, 2:00 -->
- <country code="lv">
- <id>Europe/Riga</id>
- </country>
-
- <!-- LIBYAN ARAB JAMAHIRIYA, 2:00 -->
- <country code="ly">
- <id>Africa/Tripoli</id>
- </country>
-
- <!-- MOROCCO, 0:00 -->
- <country code="ma">
- <id>Africa/Casablanca</id>
- </country>
-
- <!-- MONACO, 1:00 -->
- <country code="mc">
- <id>Europe/Monaco</id>
- </country>
-
- <!-- MOLDOVA, 2:00 -->
- <country code="md">
- <id>Europe/Chisinau</id>
- </country>
-
- <!-- MONTENEGRO, 1:00 -->
- <country code="me">
- <id>Europe/Podgorica</id>
- </country>
-
- <!-- Collectivity of Saint Martin, -4:00 -->
- <country code="mf">
- <id>America/Marigot</id>
- </country>
-
- <!-- MADAGASCAR, 3:00 -->
- <country code="mg">
- <id>Indian/Antananarivo</id>
- </country>
-
- <!-- MARSHALL ISLANDS, 12:00 -->
- <country code="mh">
- <id>Pacific/Majuro</id>
- <id>Pacific/Kwajalein</id>
- </country>
-
- <!-- MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF, 1:00 -->
- <country code="mk">
- <id>Europe/Skopje</id>
- </country>
-
- <!-- MALI, 0:00 -->
- <country code="ml">
- <id>Africa/Bamako</id>
- </country>
-
- <!-- MYANMAR, 6:30 -->
- <country code="mm">
- <id>Asia/Yangon</id>
- </country>
-
- <!-- MONGOLIA -->
- <country code="mn">
- <!-- 8:00 -->
- <id>Asia/Choibalsan</id>
- <id>Asia/Ulaanbaatar</id>
-
- <!-- 7:00 -->
- <id>Asia/Hovd</id>
- </country>
-
- <!-- MACAO, 8:00 -->
- <country code="mo">
- <id>Asia/Macau</id>
- </country>
-
- <!-- NORTHERN MARIANA ISLANDS, 10:00 -->
- <country code="mp">
- <id>Pacific/Saipan</id>
- </country>
-
- <!-- MARTINIQUE, -4:00 -->
- <country code="mq">
- <id>America/Martinique</id>
- </country>
-
- <!-- MAURITANIA, 0:00 -->
- <country code="mr">
- <id>Africa/Nouakchott</id>
- </country>
-
- <!-- MONTSERRAT, -4:00 -->
- <country code="ms">
- <id>America/Montserrat</id>
- </country>
-
- <!-- MALTA, 1:00 -->
- <country code="mt">
- <id>Europe/Malta</id>
- </country>
-
- <!-- MAURITIUS, 4:00 -->
- <country code="mu">
- <id>Indian/Mauritius</id>
- </country>
-
- <!-- MALDIVES, 5:00 -->
- <country code="mv">
- <id>Indian/Maldives</id>
- </country>
-
- <!-- MALAWI, 2:00 -->
- <country code="mw">
- <id>Africa/Blantyre</id>
- </country>
-
- <!-- MEXICO -->
- <country code="mx">
- <!-- -6:00 -->
- <id>America/Mexico_City</id>
- <id>America/Merida</id>
- <id>America/Monterrey</id>
- <id>America/Matamoros</id>
- <id>America/Bahia_Banderas</id>
-
- <!-- -5:00 -->
- <id>America/Cancun</id>
-
- <!-- -7:00 -->
- <id>America/Chihuahua</id>
- <id>America/Hermosillo</id>
- <id>America/Mazatlan</id>
- <id>America/Ojinaga</id>
-
- <!-- -8:00 -->
- <id>America/Tijuana</id>
- </country>
-
- <!-- MALAYSIA, 8:00 -->
- <country code="my">
- <id>Asia/Kuala_Lumpur</id>
- <id>Asia/Kuching</id>
- </country>
-
- <!-- MOZAMBIQUE, 2:00 -->
- <country code="mz">
- <id>Africa/Maputo</id>
- </country>
-
- <!-- NAMIBIA, 1:00 -->
- <country code="na">
- <id>Africa/Windhoek</id>
- </country>
-
- <!-- NEW CALEDONIA, 11:00 -->
- <country code="nc">
- <id>Pacific/Noumea</id>
- </country>
-
- <!-- NIGER, 1:00 -->
- <country code="ne">
- <id>Africa/Niamey</id>
- </country>
-
- <!-- NORFOLK ISLAND, 11:30 -->
- <country code="nf">
- <id>Pacific/Norfolk</id>
- </country>
-
- <!-- NIGERIA, 1:00 -->
- <country code="ng">
- <id>Africa/Lagos</id>
- </country>
-
- <!-- NICARAGUA, -6:00 -->
- <country code="ni">
- <id>America/Managua</id>
- </country>
-
- <!-- NETHERLANDS, 1:00 -->
- <country code="nl">
- <id>Europe/Amsterdam</id>
- </country>
-
- <!-- NORWAY, 1:00 -->
- <country code="no">
- <id>Europe/Oslo</id>
- </country>
-
- <!-- NEPAL, 5:45 -->
- <country code="np">
- <id>Asia/Kathmandu</id>
- </country>
-
- <!-- NAURU, 12:00 -->
- <country code="nr">
- <id>Pacific/Nauru</id>
- </country>
-
- <!-- NIUE, -11:00 -->
- <country code="nu">
- <id>Pacific/Niue</id>
- </country>
-
- <!-- NEW ZEALAND, 12:00 -->
- <country code="nz">
- <!-- 12:00 -->
- <id>Pacific/Auckland</id>
-
- <!-- 12:45 -->
- <id>Pacific/Chatham</id>
- </country>
-
- <!-- OMAN, 4:00 -->
- <country code="om">
- <id>Asia/Muscat</id>
- </country>
-
- <!-- PANAMA, -5:00 -->
- <country code="pa">
- <id>America/Panama</id>
- </country>
-
- <!-- PERU, -5:00 -->
- <country code="pe">
- <id>America/Lima</id>
- </country>
-
- <!-- FRENCH POLYNESIA -->
- <country code="pf">
- <!-- -9:00 -->
- <id>Pacific/Gambier</id>
-
- <!-- -9:30 -->
- <id>Pacific/Marquesas</id>
-
- <!-- -10:00 -->
- <id>Pacific/Tahiti</id>
- </country>
-
- <!-- PAPUA NEW GUINEA -->
- <country code="pg">
- <!-- 10:00 -->
- <id>Pacific/Port_Moresby</id>
-
- <!-- 11:00 -->
- <id>Pacific/Bougainville</id>
- </country>
-
- <!-- PHILIPPINES, 8:00 -->
- <country code="ph">
- <id>Asia/Manila</id>
- </country>
-
- <!-- PAKISTAN, 5:00 -->
- <country code="pk">
- <id>Asia/Karachi</id>
- </country>
-
- <!-- POLAND, 1:00 -->
- <country code="pl">
- <id>Europe/Warsaw</id>
- </country>
-
- <!-- SAINT PIERRE AND MIQUELON, -3:00 -->
- <country code="pm">
- <id>America/Miquelon</id>
- </country>
-
- <!-- PITCAIRN, -8:00 -->
- <country code="pn">
- <id>Pacific/Pitcairn</id>
- </country>
-
- <!-- PUERTO RICO, -4:00 -->
- <country code="pr">
- <id>America/Puerto_Rico</id>
- </country>
-
- <!-- PALESTINE, 2:00 -->
- <country code="ps">
- <id>Asia/Gaza</id>
- <id>Asia/Hebron</id>
- </country>
-
- <!-- PORTUGAL -->
- <country code="pt">
- <!-- 0:00 -->
- <id>Europe/Lisbon</id>
- <id>Atlantic/Madeira</id>
-
- <!-- -1:00 -->
- <id>Atlantic/Azores</id>
- </country>
-
- <!-- PALAU, 9:00 -->
- <country code="pw">
- <id>Pacific/Palau</id>
- </country>
-
- <!-- PARAGUAY, -4:00 -->
- <country code="py">
- <id>America/Asuncion</id>
- </country>
-
- <!-- QATAR, 3:00 -->
- <country code="qa">
- <id>Asia/Qatar</id>
- </country>
-
- <!-- REUNION, 4:00 -->
- <country code="re">
- <id>Indian/Reunion</id>
- </country>
-
- <!-- ROMANIA, 2:00 -->
- <country code="ro">
- <id>Europe/Bucharest</id>
- </country>
-
- <!-- SERBIA, 1:00 -->
- <country code="rs">
- <id>Europe/Belgrade</id>
- </country>
-
- <!-- RUSSIAN FEDERATION -->
- <country code="ru">
- <!-- 12:00 -->
- <id>Asia/Kamchatka</id>
- <id>Asia/Anadyr</id>
-
- <!-- 11:00 -->
- <id>Asia/Magadan</id>
- <id>Asia/Sakhalin</id>
- <id>Asia/Srednekolymsk</id>
-
- <!-- 10:00 -->
- <id>Asia/Vladivostok</id>
- <id>Asia/Ust-Nera</id>
-
- <!-- 9:00 -->
- <id>Asia/Yakutsk</id>
- <id>Asia/Chita</id>
- <id>Asia/Khandyga</id>
-
- <!-- 8:00 -->
- <id>Asia/Irkutsk</id>
-
- <!-- 7:00 -->
- <id>Asia/Krasnoyarsk</id>
- <id>Asia/Novosibirsk</id>
- <id>Asia/Barnaul</id>
- <id>Asia/Novokuznetsk</id>
- <id>Asia/Tomsk</id>
-
- <!-- 6:00 -->
- <id>Asia/Omsk</id>
-
- <!-- 5:00 -->
- <id>Asia/Yekaterinburg</id>
-
- <!-- 4:00 -->
- <id>Europe/Samara</id>
- <id>Europe/Astrakhan</id>
- <id>Europe/Ulyanovsk</id>
- <id>Europe/Saratov</id>
-
- <!-- 3:00 -->
- <id>Europe/Moscow</id>
- <id>Europe/Volgograd</id>
- <id>Europe/Kirov</id>
- <id>Europe/Simferopol</id>
-
- <!-- 2:00 -->
- <id>Europe/Kaliningrad</id>
- </country>
-
- <!-- RWANDA, 2:00 -->
- <country code="rw">
- <id>Africa/Kigali</id>
- </country>
-
- <!-- SAUDI ARABIA, 3:00 -->
- <country code="sa">
- <id>Asia/Riyadh</id>
- </country>
-
- <!-- SOLOMON ISLANDS, 11:00 -->
- <country code="sb">
- <id>Pacific/Guadalcanal</id>
- </country>
-
- <!-- SEYCHELLES, 4:00 -->
- <country code="sc">
- <id>Indian/Mahe</id>
- </country>
-
- <!-- SUDAN, 3:00 -->
- <country code="sd">
- <id>Africa/Khartoum</id>
- </country>
-
- <!-- SWEDEN, 1:00 -->
- <country code="se">
- <id>Europe/Stockholm</id>
- </country>
-
- <!-- SINGAPORE, 8:00 -->
- <country code="sg">
- <id>Asia/Singapore</id>
- </country>
-
- <!-- SAINT HELENA, 0:00 -->
- <country code="sh">
- <id>Atlantic/St_Helena</id>
- </country>
-
- <!-- SLOVENIA, 1:00 -->
- <country code="si">
- <id>Europe/Ljubljana</id>
- </country>
-
- <!-- SVALBARD AND JAN MAYEN, 1:00 -->
- <country code="sj">
- <id>Arctic/Longyearbyen</id>
- </country>
-
- <!-- SLOVAKIA, 1:00 -->
- <country code="sk">
- <id>Europe/Bratislava</id>
- </country>
-
- <!-- SIERRA LEONE, 0:00 -->
- <country code="sl">
- <id>Africa/Freetown</id>
- </country>
-
- <!-- SAN MARINO, 1:00 -->
- <country code="sm">
- <id>Europe/San_Marino</id>
- </country>
-
- <!-- SENEGAL, 0:00 -->
- <country code="sn">
- <id>Africa/Dakar</id>
- </country>
-
- <!-- SOMALIA, 3:00 -->
- <country code="so">
- <id>Africa/Mogadishu</id>
- </country>
-
- <!-- SURINAME, -3:00 -->
- <country code="sr">
- <id>America/Paramaribo</id>
- </country>
-
- <!-- South Sudan, 3:00 -->
- <country code="ss">
- <id>Africa/Juba</id>
- </country>
-
- <!-- SAO TOME AND PRINCIPE, 0:00 -->
- <country code="st">
- <id>Africa/Sao_Tome</id>
- </country>
-
- <!-- EL SALVADOR, -6:00 -->
- <country code="sv">
- <id>America/El_Salvador</id>
- </country>
-
- <!-- Sint Maarten, -4:00 -->
- <country code="sx">
- <id>America/Lower_Princes</id>
- </country>
-
- <!-- SYRIAN ARAB REPUBLIC, 2:00 -->
- <country code="sy">
- <id>Asia/Damascus</id>
- </country>
-
- <!-- SWAZILAND, 2:00 -->
- <country code="sz">
- <id>Africa/Mbabane</id>
- </country>
-
- <!-- TURKS AND CAICOS ISLANDS, -4:00 -->
- <country code="tc">
- <id>America/Grand_Turk</id>
- </country>
-
- <!-- CHAD, 1:00 -->
- <country code="td">
- <id>Africa/Ndjamena</id>
- </country>
-
- <!-- FRENCH SOUTHERN TERRITORIES -->
- <country code="tf">
- <!-- 5:00 -->
- <id>Indian/Kerguelen</id>
- </country>
-
- <!-- TOGO, 0:00 -->
- <country code="tg">
- <id>Africa/Lome</id>
- </country>
-
- <!-- THAILAND, 7:00 -->
- <country code="th">
- <id>Asia/Bangkok</id>
- </country>
-
- <!-- TAJIKISTAN, 5:00 -->
- <country code="tj">
- <id>Asia/Dushanbe</id>
- </country>
-
- <!-- TOKELAU, +13:00 -->
- <country code="tk">
- <id>Pacific/Fakaofo</id>
- </country>
-
- <!-- TIMOR-LESTE, 9:00 -->
- <country code="tl">
- <id>Asia/Dili</id>
- </country>
-
- <!-- TURKMENISTAN, 5:00 -->
- <country code="tm">
- <id>Asia/Ashgabat</id>
- </country>
-
- <!-- TUNISIA, 1:00 -->
- <country code="tn">
- <id>Africa/Tunis</id>
- </country>
-
- <!-- TONGA, 13:00 -->
- <country code="to">
- <id>Pacific/Tongatapu</id>
- </country>
-
- <!-- TURKEY, 3:00 -->
- <country code="tr">
- <id>Europe/Istanbul</id>
- </country>
-
- <!-- TRINIDAD AND TOBAGO, -4:00 -->
- <country code="tt">
- <id>America/Port_of_Spain</id>
- </country>
-
- <!-- TUVALU, 12:00 -->
- <country code="tv">
- <id>Pacific/Funafuti</id>
- </country>
-
- <!-- TAIWAN, PROVINCE OF CHINA, 8:00 -->
- <country code="tw">
- <id>Asia/Taipei</id>
- </country>
-
- <!-- TANZANIA, UNITED REPUBLIC OF, 3:00 -->
- <country code="tz">
- <id>Africa/Dar_es_Salaam</id>
- </country>
-
- <!-- UKRAINE, 2:00 -->
- <country code="ua">
- <id>Europe/Kiev</id>
- <id>Europe/Uzhgorod</id>
- <id>Europe/Zaporozhye</id>
- </country>
-
- <!-- UGANDA, 3:00 -->
- <country code="ug">
- <id>Africa/Kampala</id>
- </country>
-
- <!-- UNITED STATES MINOR OUTLYING ISLANDS -->
- <country code="um">
- <!-- 12:00 -->
- <id>Pacific/Wake</id>
-
- <!-- -11:00 -->
- <id>Pacific/Midway</id>
- </country>
-
- <!-- UNITED STATES -->
- <country code="us">
- <!-- -5:00 -->
- <id>America/New_York</id>
- <id>America/Detroit</id>
- <id>America/Kentucky/Louisville</id>
- <id>America/Kentucky/Monticello</id>
- <id>America/Indiana/Indianapolis</id>
- <id>America/Indiana/Vincennes</id>
- <id>America/Indiana/Winamac</id>
- <id>America/Indiana/Marengo</id>
- <id>America/Indiana/Petersburg</id>
- <id>America/Indiana/Vevay</id>
-
- <!-- -6:00 -->
- <id>America/Chicago</id>
- <id>America/Indiana/Knox</id>
- <id>America/Menominee</id>
- <id>America/North_Dakota/Center</id>
- <id>America/North_Dakota/New_Salem</id>
- <id>America/Indiana/Tell_City</id>
- <id>America/North_Dakota/Beulah</id>
-
- <!-- -7:00 -->
- <id>America/Denver</id>
- <id>America/Boise</id>
- <id>America/Phoenix</id>
-
- <!-- -8:00 -->
- <id>America/Los_Angeles</id>
-
- <!-- -9:00 -->
- <id>America/Anchorage</id>
- <id>America/Juneau</id>
- <id>America/Yakutat</id>
- <id>America/Nome</id>
- <id>America/Metlakatla</id>
- <id>America/Sitka</id>
-
- <!-- -10:00 -->
- <id>Pacific/Honolulu</id>
- <id>America/Adak</id>
- </country>
-
- <!-- URUGUAY, -3:00 -->
- <country code="uy">
- <id>America/Montevideo</id>
- </country>
-
- <!-- UZBEKISTAN, 5:00 -->
- <country code="uz">
- <id>Asia/Tashkent</id>
- <id>Asia/Samarkand</id>
- </country>
-
- <!-- HOLY SEE (VATICAN CITY STATE), 1:00 -->
- <country code="va">
- <id>Europe/Vatican</id>
- </country>
-
- <!-- SAINT VINCENT AND THE GRENADINES, -4:00 -->
- <country code="vc">
- <id>America/St_Vincent</id>
- </country>
-
- <!-- VENEZUELA, -4:00 -->
- <country code="ve">
- <id>America/Caracas</id>
- </country>
-
- <!-- VIRGIN ISLANDS, BRITISH, -4:00 -->
- <country code="vg">
- <id>America/Tortola</id>
- </country>
-
- <!-- VIRGIN ISLANDS, U.S., -4:00 -->
- <country code="vi">
- <id>America/St_Thomas</id>
- </country>
-
- <!-- VIET NAM, 7:00 -->
- <country code="vn">
- <id>Asia/Ho_Chi_Minh</id>
- </country>
-
- <!-- VANUATU, 11:00 -->
- <country code="vu">
- <id>Pacific/Efate</id>
- </country>
-
- <!-- WALLIS AND FUTUNA, 12:00 -->
- <country code="wf">
- <id>Pacific/Wallis</id>
- </country>
-
- <!-- SAMOA, 13:00 -->
- <country code="ws">
- <id>Pacific/Apia</id>
- </country>
-
- <!-- YEMEN, 3:00 -->
- <country code="ye">
- <id>Asia/Aden</id>
- </country>
-
- <!-- MAYOTTE, 3:00 -->
- <country code="yt">
- <id>Indian/Mayotte</id>
- </country>
-
- <!-- SOUTH AFRICA, 2:00 -->
- <country code="za">
- <id>Africa/Johannesburg</id>
- </country>
-
- <!-- ZAMBIA, 2:00 -->
- <country code="zm">
- <id>Africa/Lusaka</id>
- </country>
-
- <!-- ZIMBABWE, 2:00 -->
- <country code="zw">
- <id>Africa/Harare</id>
- </country>
- </countryzones>
-</timezones>
diff --git a/libdl/libdl.arm.map b/libdl/libdl.arm.map
index 668f008..292bd97 100644
--- a/libdl/libdl.arm.map
+++ b/libdl/libdl.arm.map
@@ -34,11 +34,15 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -48,4 +52,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libdl/libdl.arm64.map b/libdl/libdl.arm64.map
index 8270fe9..2fe2c7b 100644
--- a/libdl/libdl.arm64.map
+++ b/libdl/libdl.arm64.map
@@ -33,11 +33,15 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -47,4 +51,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libdl/libdl.map.txt b/libdl/libdl.map.txt
index a4c6483..408d4dc 100644
--- a/libdl/libdl.map.txt
+++ b/libdl/libdl.map.txt
@@ -33,11 +33,15 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -47,4 +51,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libdl/libdl.mips.map b/libdl/libdl.mips.map
index 8270fe9..2fe2c7b 100644
--- a/libdl/libdl.mips.map
+++ b/libdl/libdl.mips.map
@@ -33,11 +33,15 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -47,4 +51,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libdl/libdl.mips64.map b/libdl/libdl.mips64.map
index 8270fe9..2fe2c7b 100644
--- a/libdl/libdl.mips64.map
+++ b/libdl/libdl.mips64.map
@@ -33,11 +33,15 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -47,4 +51,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libdl/libdl.x86.map b/libdl/libdl.x86.map
index 8270fe9..2fe2c7b 100644
--- a/libdl/libdl.x86.map
+++ b/libdl/libdl.x86.map
@@ -33,11 +33,15 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -47,4 +51,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libdl/libdl.x86_64.map b/libdl/libdl.x86_64.map
index 8270fe9..2fe2c7b 100644
--- a/libdl/libdl.x86_64.map
+++ b/libdl/libdl.x86_64.map
@@ -33,11 +33,15 @@
dlvsym; # introduced=24
} LIBC;
+LIBC_OMR1 { # future
+ global:
+ __cfi_slowpath; # future
+ __cfi_slowpath_diag; # future
+} LIBC_N;
+
LIBC_PLATFORM {
global:
__cfi_init;
- __cfi_slowpath;
- __cfi_slowpath_diag;
android_dlwarning;
android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
@@ -47,4 +51,4 @@
android_create_namespace;
android_link_namespaces;
android_get_exported_namespace;
-} LIBC_N;
+} LIBC_OMR1;
diff --git a/libm/Android.bp b/libm/Android.bp
index 07d4261..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",
@@ -529,6 +525,7 @@
sanitize: {
address: false,
coverage: false,
+ integer_overflow: false,
},
stl: "none",
}
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..ee41e45 100644
--- a/libm/freebsd-compat.h
+++ b/libm/freebsd-compat.h
@@ -28,7 +28,15 @@
#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);
+// Similarly rename _scan_nan.
+#define _scan_nan __libm_scan_nan
+
#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/linker/Android.bp b/linker/Android.bp
index efd91ac..fda7eb5 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -101,6 +101,12 @@
"-Werror",
],
+ product_variables: {
+ debuggable: {
+ cppflags: ["-DUSE_LD_CONFIG_FILE"],
+ },
+ },
+
cppflags: ["-Wold-style-cast"],
// we are going to link libc++_static manually because
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 8e7a141..4397551 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -558,9 +558,10 @@
static LoadTask* create(const char* name,
soinfo* needed_by,
+ android_namespace_t* start_from,
std::unordered_map<const soinfo*, ElfReader>* readers_map) {
LoadTask* ptr = TypeBasedAllocator<LoadTask>::alloc();
- return new (ptr) LoadTask(name, needed_by, readers_map);
+ return new (ptr) LoadTask(name, needed_by, start_from, readers_map);
}
const char* get_name() const {
@@ -612,6 +613,11 @@
is_dt_needed_ = is_dt_needed;
}
+ // returns the namespace from where we need to start loading this.
+ const android_namespace_t* get_start_from() const {
+ return start_from_;
+ }
+
const ElfReader& get_elf_reader() const {
CHECK(si_ != nullptr);
return (*elf_readers_map_)[si_];
@@ -650,10 +656,11 @@
private:
LoadTask(const char* name,
soinfo* needed_by,
+ android_namespace_t* start_from,
std::unordered_map<const soinfo*, ElfReader>* readers_map)
: name_(name), needed_by_(needed_by), si_(nullptr),
fd_(-1), close_fd_(false), file_offset_(0), elf_readers_map_(readers_map),
- is_dt_needed_(false) {}
+ is_dt_needed_(false), start_from_(start_from) {}
~LoadTask() {
if (fd_ != -1 && close_fd_) {
@@ -672,6 +679,7 @@
// TODO(dimitry): needed by workaround for http://b/26394120 (the grey-list)
bool is_dt_needed_;
// END OF WORKAROUND
+ const android_namespace_t* const start_from_;
DISALLOW_IMPLICIT_CONSTRUCTORS(LoadTask);
};
@@ -1041,7 +1049,7 @@
ZipArchiveCache* zip_archive_cache,
const char* name, soinfo *needed_by,
off64_t* file_offset, std::string* realpath) {
- TRACE("[ opening %s ]", name);
+ TRACE("[ opening %s at namespace %s]", name, ns->get_name());
// If the name contains a slash, we should attempt to open it directly and not search the paths.
if (strchr(name, '/') != nullptr) {
@@ -1146,6 +1154,27 @@
return *candidate != nullptr;
}
+static bool find_loaded_library_by_realpath(android_namespace_t* ns, const char* realpath,
+ bool search_linked_namespaces, soinfo** candidate) {
+ auto predicate = [&](soinfo* si) { return strcmp(realpath, si->get_realpath()) == 0; };
+
+ *candidate = ns->soinfo_list().find_if(predicate);
+
+ if (*candidate == nullptr && search_linked_namespaces) {
+ for (auto& link : ns->linked_namespaces()) {
+ android_namespace_t* linked_ns = link.linked_namespace();
+ soinfo* si = linked_ns->soinfo_list().find_if(predicate);
+
+ if (si != nullptr && link.is_accessible(si->get_soname())) {
+ *candidate = si;
+ return true;
+ }
+ }
+ }
+
+ return *candidate != nullptr;
+}
+
static bool load_library(android_namespace_t* ns,
LoadTask* task,
LoadTaskList* load_tasks,
@@ -1273,7 +1302,7 @@
}
for_each_dt_needed(task->get_elf_reader(), [&](const char* name) {
- load_tasks->push_back(LoadTask::create(name, si, task->get_readers_map()));
+ load_tasks->push_back(LoadTask::create(name, si, ns, task->get_readers_map()));
});
return true;
@@ -1368,8 +1397,7 @@
}
static bool find_library_in_linked_namespace(const android_namespace_link_t& namespace_link,
- LoadTask* task,
- int rtld_flags) {
+ LoadTask* task) {
android_namespace_t* ns = namespace_link.linked_namespace();
soinfo* candidate;
@@ -1394,29 +1422,10 @@
return true;
}
- // try to load the library - once namespace boundary is crossed
- // we need to load a library within separate load_group
- // to avoid using symbols from foreign namespace while.
- //
- // All symbols during relocation should be resolved within a
- // namespace to preserve library locality to a namespace.
- const char* name = task->get_name();
- if (find_libraries(ns,
- task->get_needed_by(),
- &name,
- 1,
- &candidate,
- nullptr /* ld_preloads */,
- 0 /* ld_preload_count*/,
- rtld_flags,
- nullptr /* extinfo*/,
- false /* add_as_children */,
- false /* search_linked_namespaces */)) {
- task->set_soinfo(candidate);
- return true;
- }
-
- return false;
+ // returning true with empty soinfo means that the library is okay to be
+ // loaded in the namespace buy has not yet been loaded there before.
+ task->set_soinfo(nullptr);
+ return true;
}
static bool find_library_internal(android_namespace_t* ns,
@@ -1445,9 +1454,24 @@
// if a library was not found - look into linked namespaces
for (auto& linked_namespace : ns->linked_namespaces()) {
if (find_library_in_linked_namespace(linked_namespace,
- task,
- rtld_flags)) {
- return true;
+ task)) {
+ if (task->get_soinfo() == nullptr) {
+ // try to load the library - once namespace boundary is crossed
+ // we need to load a library within separate load_group
+ // to avoid using symbols from foreign namespace while.
+ //
+ // However, actual linking is deferred until when the global group
+ // is fully identified and is applied to all namespaces.
+ // Otherwise, the libs in the linked namespace won't get symbols from
+ // the global group.
+ if (load_library(linked_namespace.linked_namespace(), task, zip_archive_cache, load_tasks, rtld_flags, false)) {
+ return true;
+ }
+ // lib was not found in the namespace. Try next linked namespace.
+ } else {
+ // lib is already loaded
+ return true;
+ }
}
}
}
@@ -1458,44 +1482,6 @@
static void soinfo_unload(soinfo* si);
static void soinfo_unload(soinfo* soinfos[], size_t count);
-// TODO: this is slightly unusual way to construct
-// the global group for relocation. Not every RTLD_GLOBAL
-// library is included in this group for backwards-compatibility
-// reasons.
-//
-// This group consists of the main executable, LD_PRELOADs
-// and libraries with the DF_1_GLOBAL flag set.
-static soinfo_list_t make_global_group(android_namespace_t* ns) {
- soinfo_list_t global_group;
- ns->soinfo_list().for_each([&](soinfo* si) {
- if ((si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
- global_group.push_back(si);
- }
- });
-
- return global_group;
-}
-
-// This function provides a list of libraries to be shared
-// by the namespace. For the default namespace this is the global
-// group (see make_global_group). For all others this is a group
-// of RTLD_GLOBAL libraries (which includes the global group from
-// the default namespace).
-static soinfo_list_t get_shared_group(android_namespace_t* ns) {
- if (ns == &g_default_namespace) {
- return make_global_group(ns);
- }
-
- soinfo_list_t shared_group;
- ns->soinfo_list().for_each([&](soinfo* si) {
- if ((si->get_rtld_flags() & RTLD_GLOBAL) != 0) {
- shared_group.push_back(si);
- }
- });
-
- return shared_group;
-}
-
static void shuffle(std::vector<LoadTask*>* v) {
for (size_t i = 0, size = v->size(); i < size; ++i) {
size_t n = size - i;
@@ -1518,19 +1504,17 @@
int rtld_flags,
const android_dlextinfo* extinfo,
bool add_as_children,
- bool search_linked_namespaces) {
+ bool search_linked_namespaces,
+ std::unordered_map<const soinfo*, ElfReader>& readers_map,
+ std::vector<android_namespace_t*>* namespaces) {
// Step 0: prepare.
LoadTaskList load_tasks;
- std::unordered_map<const soinfo*, ElfReader> readers_map;
for (size_t i = 0; i < library_names_count; ++i) {
const char* name = library_names[i];
- load_tasks.push_back(LoadTask::create(name, start_with, &readers_map));
+ load_tasks.push_back(LoadTask::create(name, start_with, ns, &readers_map));
}
- // Construct global_group.
- soinfo_list_t global_group = make_global_group(ns);
-
// If soinfos array is null allocate one on stack.
// The array is needed in case of failure; for example
// when library_names[] = {libone.so, libtwo.so} and libone.so
@@ -1570,7 +1554,12 @@
task->set_extinfo(is_dt_needed ? nullptr : extinfo);
task->set_dt_needed(is_dt_needed);
- if (!find_library_internal(ns,
+ // try to find the load.
+ // Note: start from the namespace that is stored in the LoadTask. This namespace
+ // is different from the current namespace when the LoadTask is for a transitive
+ // dependency and the lib that created the LoadTask is not found in the
+ // current namespace but in one of the linked namespace.
+ if (!find_library_internal(const_cast<android_namespace_t*>(task->get_start_from()),
task,
&zip_archive_cache,
&load_tasks,
@@ -1629,18 +1618,61 @@
}
}
- // Step 4: Add LD_PRELOADed libraries to the global group for
- // future runs. There is no need to explicitly add them to
- // the global group for this run because they are going to
- // appear in the local group in the correct order.
+ // Step 4: Construct the global group. Note: DF_1_GLOBAL bit of a library is
+ // determined at step 3.
+
+ // Step 4-1: DF_1_GLOBAL bit is force set for LD_PRELOADed libs because they
+ // must be added to the global group
if (ld_preloads != nullptr) {
for (auto&& si : *ld_preloads) {
si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
}
}
+ // Step 4-2: Gather all DF_1_GLOBAL libs which were newly loaded during this
+ // run. These will be the new member of the global group
+ soinfo_list_t new_global_group_members;
+ for (auto&& task : load_tasks) {
+ soinfo* si = task->get_soinfo();
+ if (!si->is_linked() && (si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
+ new_global_group_members.push_back(si);
+ }
+ }
- // Step 5: link libraries.
+ // Step 4-3: Add the new global group members to all the linked namespaces
+ for (auto si : new_global_group_members) {
+ for (auto linked_ns : *namespaces) {
+ if (si->get_primary_namespace() != linked_ns) {
+ linked_ns->add_soinfo(si);
+ si->add_secondary_namespace(linked_ns);
+ }
+ }
+ }
+
+ // Step 5: link libraries that are not destined to this namespace.
+ // Do this by recursively calling find_libraries on the namespace where the lib
+ // was found during Step 1.
+ for (auto&& task : load_tasks) {
+ soinfo* si = task->get_soinfo();
+ if (si->get_primary_namespace() != ns) {
+ const char* name = task->get_name();
+ if (find_libraries(si->get_primary_namespace(), task->get_needed_by(), &name, 1,
+ nullptr /* soinfos */, nullptr /* ld_preloads */, 0 /* ld_preload_count */,
+ rtld_flags, nullptr /* extinfo */, false /* add_as_children */,
+ false /* search_linked_namespaces */, readers_map, namespaces)) {
+ // If this lib is directly needed by one of the libs in this namespace,
+ // then increment the count
+ soinfo* needed_by = task->get_needed_by();
+ if (needed_by != nullptr && needed_by->get_primary_namespace() == ns && si->is_linked()) {
+ si->increment_ref_count();
+ }
+ } else {
+ return false;
+ }
+ }
+ }
+
+ // Step 6: link libraries in this namespace
soinfo_list_t local_group;
walk_dependencies_tree(
(start_with != nullptr && add_as_children) ? &start_with : soinfos,
@@ -1654,6 +1686,7 @@
}
});
+ soinfo_list_t global_group = ns->get_global_group();
bool linked = local_group.visit([&](soinfo* si) {
if (!si->is_linked()) {
if (!si->link_image(global_group, local_group, extinfo) ||
@@ -1684,6 +1717,9 @@
soinfo* needed_by) {
soinfo* si;
+ // readers_map is shared across recursive calls to find_libraries.
+ // However, the map is not shared across different threads.
+ std::unordered_map<const soinfo*, ElfReader> readers_map;
if (name == nullptr) {
si = solist_get_somain();
} else if (!find_libraries(ns,
@@ -1696,7 +1732,8 @@
rtld_flags,
extinfo,
false /* add_as_children */,
- true /* search_linked_namespaces */)) {
+ true /* search_linked_namespaces */,
+ readers_map)) {
return nullptr;
}
@@ -1956,12 +1993,18 @@
const char* translated_name = name;
if (g_is_asan && translated_name != nullptr && translated_name[0] == '/') {
- char translated_path[PATH_MAX];
- if (realpath(translated_name, translated_path) != nullptr) {
- asan_name_holder = std::string(kAsanLibDirPrefix) + translated_path;
+ char original_path[PATH_MAX];
+ if (realpath(name, original_path) != nullptr) {
+ asan_name_holder = std::string(kAsanLibDirPrefix) + original_path;
if (file_exists(asan_name_holder.c_str())) {
- translated_name = asan_name_holder.c_str();
- PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
+ soinfo* si = nullptr;
+ if (find_loaded_library_by_realpath(ns, original_path, true, &si)) {
+ PRINT("linker_asan dlopen NOT translating \"%s\" -> \"%s\": library already loaded", name,
+ asan_name_holder.c_str());
+ } else {
+ PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
+ translated_name = asan_name_holder.c_str();
+ }
}
}
}
@@ -2208,7 +2251,7 @@
}
} else {
// If not shared - copy only the shared group
- add_soinfos_to_namespace(get_shared_group(parent_namespace), ns);
+ add_soinfos_to_namespace(parent_namespace->get_shared_group(), ns);
}
ns->set_ld_library_paths(std::move(ld_library_paths));
@@ -3413,7 +3456,7 @@
return true;
}
-static void init_default_namespace_no_config(bool is_asan) {
+static std::vector<android_namespace_t*> init_default_namespace_no_config(bool is_asan) {
g_default_namespace.set_isolated(false);
auto default_ld_paths = is_asan ? kAsanDefaultLdPaths : kDefaultLdPaths;
@@ -3428,9 +3471,13 @@
}
g_default_namespace.set_default_library_paths(std::move(ld_default_paths));
+
+ std::vector<android_namespace_t*> namespaces;
+ namespaces.push_back(&g_default_namespace);
+ return namespaces;
}
-void init_default_namespace(const char* executable_path) {
+std::vector<android_namespace_t*> init_default_namespaces(const char* executable_path) {
g_default_namespace.set_name("(default)");
soinfo* somain = solist_get_somain();
@@ -3447,14 +3494,24 @@
std::string error_msg;
- if (!Config::read_binary_config(kLdConfigFilePath,
+ const char* config_file = kLdConfigFilePath;
+#ifdef USE_LD_CONFIG_FILE
+ // This is a debugging/testing only feature. Must not be available on
+ // production builds.
+ const char* ld_config_file = getenv("LD_CONFIG_FILE");
+ if (ld_config_file != nullptr && file_exists(ld_config_file)) {
+ config_file = ld_config_file;
+ }
+#endif
+
+ if (!Config::read_binary_config(config_file,
executable_path,
g_is_asan,
&config,
&error_msg)) {
if (!error_msg.empty()) {
DL_WARN("error reading config file \"%s\" for \"%s\" (will use default configuration): %s",
- kLdConfigFilePath,
+ config_file,
executable_path,
error_msg.c_str());
}
@@ -3462,8 +3519,7 @@
}
if (config == nullptr) {
- init_default_namespace_no_config(g_is_asan);
- return;
+ return init_default_namespace_no_config(g_is_asan);
}
const auto& namespace_configs = config->namespace_configs();
@@ -3514,10 +3570,17 @@
soinfo* ld_android_so = solist_get_head();
for (auto it : namespaces) {
it.second->add_soinfo(ld_android_so);
- // TODO (dimitry): somain and ld_preloads should probably be added to all of these namespaces too?
+ // somain and ld_preloads are added to these namespaces after LD_PRELOAD libs are linked
}
set_application_target_sdk_version(config->target_sdk_version());
+
+ std::vector<android_namespace_t*> created_namespaces;
+ created_namespaces.reserve(namespaces.size());
+ for (auto kv : namespaces) {
+ created_namespaces.push_back(kv.second);
+ }
+ return created_namespaces;
}
// This function finds a namespace exported in ld.config.txt by its name.
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index 2bdde1e..0a9aeab 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -371,15 +371,6 @@
bool is_asan,
const Config** config,
std::string* error_msg) {
- // TODO(b/38114603) Currently, multiple namespaces does not support ASAN mode
- // where some symbols should be intercepted via LD_PRELOAD; LD_PRELOADed libs
- // are not being preloaded into the linked namespaces other than the default
- // namespace. Until we fix the problem, we temporarily disable ld.config.txt
- // in ASAN mode.
- if (is_asan) {
- return false;
- }
-
g_config.clear();
std::unordered_map<std::string, PropertyValue> property_map;
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 5dc215f..0f691c3 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -87,6 +87,7 @@
// prev will never be null, because the first entry in solist is
// always the static libdl_info.
+ CHECK(prev != nullptr);
prev->next = si->next;
if (si == sonext) {
sonext = prev;
@@ -137,8 +138,7 @@
// An empty list of soinfos
static soinfo_list_t g_empty_list;
-static void add_vdso(KernelArgumentBlock& args __unused) {
-#if defined(AT_SYSINFO_EHDR)
+static void add_vdso(KernelArgumentBlock& args) {
ElfW(Ehdr)* ehdr_vdso = reinterpret_cast<ElfW(Ehdr)*>(args.getauxval(AT_SYSINFO_EHDR));
if (ehdr_vdso == nullptr) {
return;
@@ -154,7 +154,6 @@
si->prelink_image();
si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr);
-#endif
}
/* gdb expects the linker to be in the debug shared object list.
@@ -307,6 +306,11 @@
break;
}
}
+
+ if (si->base == 0) {
+ async_safe_fatal("Could not find a PHDR: broken executable?");
+ }
+
si->dynamic = nullptr;
ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(si->base);
@@ -333,7 +337,7 @@
somain = si;
- init_default_namespace(executable_path);
+ std::vector<android_namespace_t*> namespaces = init_default_namespaces(executable_path);
if (!si->prelink_image()) {
async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
@@ -341,6 +345,13 @@
// add somain to global group
si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
+ // ... and add it to all other linked namespaces
+ for (auto linked_ns : namespaces) {
+ if (linked_ns != &g_default_namespace) {
+ linked_ns->add_soinfo(somain);
+ somain->add_secondary_namespace(linked_ns);
+ }
+ }
// Load ld_preloads and dependencies.
std::vector<const char*> needed_library_name_list;
@@ -358,6 +369,9 @@
const char** needed_library_names = &needed_library_name_list[0];
size_t needed_libraries_count = needed_library_name_list.size();
+ // readers_map is shared across recursive calls to find_libraries so that we
+ // don't need to re-load elf headers.
+ std::unordered_map<const soinfo*, ElfReader> readers_map;
if (needed_libraries_count > 0 &&
!find_libraries(&g_default_namespace,
si,
@@ -369,7 +383,9 @@
RTLD_GLOBAL,
nullptr,
true /* add_as_children */,
- true /* search_linked_namespaces */)) {
+ true /* search_linked_namespaces */,
+ readers_map,
+ &namespaces)) {
async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
} else if (needed_libraries_count == 0) {
if (!si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr)) {
@@ -488,6 +504,15 @@
static uintptr_t linktime_addr = reinterpret_cast<uintptr_t>(&linktime_addr);
ElfW(Addr) linker_addr = reinterpret_cast<uintptr_t>(&linktime_addr) - linktime_addr;
+#if defined(__clang_analyzer__)
+ // The analyzer assumes that linker_addr will always be null. Make it an
+ // unknown value so we don't have to mark N places with NOLINTs.
+ //
+ // (`+=`, rather than `=`, allows us to sidestep a potential "unused store"
+ // complaint)
+ linker_addr += reinterpret_cast<uintptr_t>(raw_args);
+#endif
+
ElfW(Addr) entry_point = args.getauxval(AT_ENTRY);
ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_addr);
ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_addr + elf_hdr->e_phoff);
diff --git a/linker/linker_main.h b/linker/linker_main.h
index 8f3f07c..2cf30c2 100644
--- a/linker/linker_main.h
+++ b/linker/linker_main.h
@@ -31,6 +31,9 @@
#include <android/dlext.h>
+#include <unordered_map>
+#include <vector>
+
#include "linker_namespaces.h"
#include "linker_soinfo.h"
@@ -44,7 +47,9 @@
static size_t ref_count_;
};
-void init_default_namespace(const char* executable_path);
+class ElfReader;
+
+std::vector<android_namespace_t*> init_default_namespaces(const char* executable_path);
soinfo* soinfo_alloc(android_namespace_t* ns, const char* name,
struct stat* file_stat, off64_t file_offset,
uint32_t rtld_flags);
@@ -59,7 +64,9 @@
int rtld_flags,
const android_dlextinfo* extinfo,
bool add_as_children,
- bool search_linked_namespaces);
+ bool search_linked_namespaces,
+ std::unordered_map<const soinfo*, ElfReader>& readers_map,
+ std::vector<android_namespace_t*>* namespaces = nullptr);
void solist_add_soinfo(soinfo* si);
bool solist_remove_soinfo(soinfo* si);
diff --git a/linker/linker_namespaces.cpp b/linker/linker_namespaces.cpp
index 3c86f99..9fdf0b5 100644
--- a/linker/linker_namespaces.cpp
+++ b/linker/linker_namespaces.cpp
@@ -31,6 +31,8 @@
#include "linker_soinfo.h"
#include "linker_utils.h"
+#include <dlfcn.h>
+
bool android_namespace_t::is_accessible(const std::string& file) {
if (!is_isolated_) {
return true;
@@ -86,3 +88,41 @@
return !is_accessible_ftor(si);
});
}
+
+// TODO: this is slightly unusual way to construct
+// the global group for relocation. Not every RTLD_GLOBAL
+// library is included in this group for backwards-compatibility
+// reasons.
+//
+// This group consists of the main executable, LD_PRELOADs
+// and libraries with the DF_1_GLOBAL flag set.
+soinfo_list_t android_namespace_t::get_global_group() {
+ soinfo_list_t global_group;
+ soinfo_list().for_each([&](soinfo* si) {
+ if ((si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
+ global_group.push_back(si);
+ }
+ });
+
+ return global_group;
+}
+
+// This function provides a list of libraries to be shared
+// by the namespace. For the default namespace this is the global
+// group (see get_global_group). For all others this is a group
+// of RTLD_GLOBAL libraries (which includes the global group from
+// the default namespace).
+soinfo_list_t android_namespace_t::get_shared_group() {
+ if (this == &g_default_namespace) {
+ return get_global_group();
+ }
+
+ soinfo_list_t shared_group;
+ soinfo_list().for_each([&](soinfo* si) {
+ if ((si->get_rtld_flags() & RTLD_GLOBAL) != 0) {
+ shared_group.push_back(si);
+ }
+ });
+
+ return shared_group;
+}
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index 1099b6b..16906d6 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -136,6 +136,9 @@
// or one of it's parent soinfos belongs to this namespace.
bool is_accessible(soinfo* si);
+ soinfo_list_t get_global_group();
+ soinfo_list_t get_shared_group();
+
private:
const char* name_;
bool is_isolated_;
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 42c29c8..a9873c4 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -147,8 +147,9 @@
}
bool ElfReader::Read(const char* name, int fd, off64_t file_offset, off64_t file_size) {
- CHECK(!did_read_);
- CHECK(!did_load_);
+ if (did_read_) {
+ return true;
+ }
name_ = name;
fd_ = fd;
file_offset_ = file_offset;
@@ -167,7 +168,9 @@
bool ElfReader::Load(const android_dlextinfo* extinfo) {
CHECK(did_read_);
- CHECK(!did_load_);
+ if (did_load_) {
+ return true;
+ }
if (ReserveAddressSpace(extinfo) &&
LoadSegments() &&
FindPhdr()) {
diff --git a/linker/tests/linker_config_test.cpp b/linker/tests/linker_config_test.cpp
index b024011..c6fade9 100644
--- a/linker/tests/linker_config_test.cpp
+++ b/linker/tests/linker_config_test.cpp
@@ -33,6 +33,7 @@
#include <gtest/gtest.h>
#include "../linker_config.h"
+#include "../linker_utils.h"
#include <unistd.h>
@@ -41,6 +42,11 @@
#include <android-base/file.h>
#include <android-base/test_utils.h>
+#if defined(__LP64__)
+#define ARCH_SUFFIX "64"
+#else
+#define ARCH_SUFFIX ""
+#endif
static const char* config_str =
"# comment \n"
@@ -70,40 +76,28 @@
return android::base::WriteStringToFile(content, path);
}
+static std::vector<std::string> resolve_paths(std::vector<std::string> paths) {
+ std::vector<std::string> resolved_paths;
+ resolve_paths(paths, &resolved_paths);
+ return resolved_paths;
+}
+
static void run_linker_config_smoke_test(bool is_asan) {
-#if defined(__LP64__)
- const std::vector<std::string> kExpectedDefaultSearchPath = is_asan ?
- std::vector<std::string>({ "/data", "/vendor/lib64"}) :
- std::vector<std::string>({ "/vendor/lib64" });
+ const std::vector<std::string> kExpectedDefaultSearchPath =
+ resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/vendor/lib" ARCH_SUFFIX }) :
+ std::vector<std::string>({ "/vendor/lib" ARCH_SUFFIX }));
- const std::vector<std::string> kExpectedDefaultPermittedPath = is_asan ?
- std::vector<std::string>({ "/data", "/vendor" }) :
- std::vector<std::string>({ "/vendor/lib64" });
+ const std::vector<std::string> kExpectedDefaultPermittedPath =
+ resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/vendor" }) :
+ std::vector<std::string>({ "/vendor/lib" ARCH_SUFFIX }));
- const std::vector<std::string> kExpectedSystemSearchPath = is_asan ?
- std::vector<std::string>({ "/data", "/system/lib64" }) :
- std::vector<std::string>({ "/system/lib64" });
+ const std::vector<std::string> kExpectedSystemSearchPath =
+ resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/system/lib" ARCH_SUFFIX }) :
+ std::vector<std::string>({ "/system/lib" ARCH_SUFFIX }));
- const std::vector<std::string> kExpectedSystemPermittedPath = is_asan ?
- std::vector<std::string>({ "/data", "/system" }) :
- std::vector<std::string>({ "/system/lib64" });
-#else
- const std::vector<std::string> kExpectedDefaultSearchPath = is_asan ?
- std::vector<std::string>({ "/data", "/vendor/lib"}) :
- std::vector<std::string>({ "/vendor/lib" });
-
- const std::vector<std::string> kExpectedDefaultPermittedPath = is_asan ?
- std::vector<std::string>({ "/data", "/vendor" }) :
- std::vector<std::string>({ "/vendor/lib" });
-
- const std::vector<std::string> kExpectedSystemSearchPath = is_asan ?
- std::vector<std::string>({ "/data", "/system/lib" }) :
- std::vector<std::string>({ "/system/lib" });
-
- const std::vector<std::string> kExpectedSystemPermittedPath = is_asan ?
- std::vector<std::string>({ "/data", "/system" }) :
- std::vector<std::string>({ "/system/lib" });
-#endif
+ const std::vector<std::string> kExpectedSystemPermittedPath =
+ resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/system" }) :
+ std::vector<std::string>({ "/system/lib" ARCH_SUFFIX }));
TemporaryFile tmp_file;
close(tmp_file.fd);
@@ -174,7 +168,6 @@
run_linker_config_smoke_test(false);
}
-// TODO(b/38114603) revive this test when ld.config.txt is enabled for ASAN mode
-//TEST(linker_config, asan_smoke) {
-// run_linker_config_smoke_test(true);
-//}
+TEST(linker_config, asan_smoke) {
+ run_linker_config_smoke_test(true);
+}
diff --git a/tests/Android.bp b/tests/Android.bp
index a03f1a6..e8fa5bd 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -61,6 +61,7 @@
"dirent_test.cpp",
"elf_test.cpp",
"endian_test.cpp",
+ "errno_test.cpp",
"error_test.cpp",
"eventfd_test.cpp",
"fcntl_test.cpp",
@@ -88,6 +89,7 @@
"nl_types_test.cpp",
"pthread_test.cpp",
"pty_test.cpp",
+ "qsort_test.cpp",
"regex_test.cpp",
"resolv_test.cpp",
"sched_test.cpp",
@@ -132,6 +134,7 @@
"sys_sysmacros_test.cpp",
"sys_time_test.cpp",
"sys_timex_test.cpp",
+ "sys_ttydefaults_test.cpp",
"sys_types_test.cpp",
"sys_uio_test.cpp",
"sys_vfs_test.cpp",
@@ -286,6 +289,7 @@
],
static_libs: [
"libpagemap",
+ "libziparchive",
"libLLVMObject",
"libLLVMBitReader",
"libLLVMMC",
@@ -294,7 +298,13 @@
"libLLVMSupport",
],
}
- }
+ },
+
+ product_variables: {
+ debuggable: {
+ cppflags: ["-DUSE_LD_CONFIG_FILE"],
+ },
+ },
}
// -----------------------------------------------------------------------------
@@ -595,6 +605,12 @@
sanitize: {
never: false,
},
+
+ product_variables: {
+ debuggable: {
+ cppflags: ["-DUSE_LD_CONFIG_FILE"],
+ },
+ },
}
subdirs = ["libs"]
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index aa8bd57..857640a 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -23,6 +23,8 @@
#include <stdint.h>
#include <string>
+#include <iostream>
+#include <fstream>
#include "gtest_globals.h"
#include "utils.h"
@@ -109,4 +111,131 @@
#endif
}
-// TODO: Add tests for LD_PRELOADs
+
+TEST(dl, exec_without_ld_preload) {
+#if defined(__BIONIC__)
+ std::string helper = get_testlib_root() +
+ "/ld_preload_test_helper/ld_preload_test_helper";
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({ helper.c_str(), nullptr });
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "12345");
+#endif
+}
+
+TEST(dl, exec_with_ld_preload) {
+#if defined(__BIONIC__)
+ std::string helper = get_testlib_root() +
+ "/ld_preload_test_helper/ld_preload_test_helper";
+ std::string env = std::string("LD_PRELOAD=") + get_testlib_root() + "/ld_preload_test_helper_lib2.so";
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({ helper.c_str(), nullptr });
+ eth.SetEnv({ env.c_str(), nullptr });
+ // ld_preload_test_helper calls get_value_from_lib() and returns the value.
+ // The symbol is defined by two libs: ld_preload_test_helper_lib.so and
+ // ld_preloaded_lib.so. The former is DT_NEEDED and the latter is LD_PRELOADED
+ // via this execution. The main executable is linked to the LD_PRELOADED lib
+ // and the value given from the lib is returned.
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "54321");
+#endif
+}
+
+
+// ld_config_test_helper must fail because it is depending on a lib which is not
+// in the search path
+//
+// Call sequence is...
+// _helper -- (get_value_from_lib()) -->
+// _lib1.so -- (get_value_from_another_lib()) -->
+// _lib2.so (returns 12345)
+// The two libs are in ns2/ subdir.
+TEST(dl, exec_without_ld_config_file) {
+#if defined(__BIONIC__)
+ std::string error_message = "CANNOT LINK EXECUTABLE \"" + get_testlib_root() + "/ld_config_test_helper/ld_config_test_helper\": library \"ld_config_test_helper_lib1.so\" not found\n";
+ std::string helper = get_testlib_root() +
+ "/ld_config_test_helper/ld_config_test_helper";
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({ helper.c_str(), nullptr });
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, -6, error_message.c_str());
+#endif
+}
+
+#if defined(__BIONIC__)
+static void create_ld_config_file(std::string& config_file) {
+ std::ofstream fout(config_file.c_str(), std::ios::out);
+ fout << "dir.test = " << get_testlib_root() << "/ld_config_test_helper/" << std::endl
+ << "[test]" << std::endl
+ << "additional.namespaces = ns2" << std::endl
+ << "namespace.default.search.paths = " << get_testlib_root() << std::endl
+ << "namespace.default.links = ns2" << std::endl
+ << "namespace.default.link.ns2.shared_libs = libc.so:libm.so:libdl.so:ld_config_test_helper_lib1.so" << std::endl
+ << "namespace.ns2.search.paths = /system/${LIB}:" << get_testlib_root() << "/ns2" << std::endl;
+ fout.close();
+}
+#endif
+
+#ifdef USE_LD_CONFIG_FILE
+
+// _lib1.so and _lib2.so are now searchable by having another namespace 'ns2'
+// whose search paths include the 'ns2/' subdir.
+TEST(dl, exec_with_ld_config_file) {
+#if defined(__BIONIC__)
+ std::string helper = get_testlib_root() +
+ "/ld_config_test_helper/ld_config_test_helper";
+ std::string config_file = get_testlib_root() + "/ld.config.txt";
+ create_ld_config_file(config_file);
+ std::string env = std::string("LD_CONFIG_FILE=") + config_file;
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({ helper.c_str(), nullptr });
+ eth.SetEnv({ env.c_str(), nullptr });
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "12345");
+#endif
+}
+
+// _lib3.so has same symbol as lib2.so but returns 54321. _lib3.so is
+// LD_PRELOADed. This test is to ensure LD_PRELOADed libs are available to
+// additional namespaces other than the default namespace.
+TEST(dl, exec_with_ld_config_file_with_ld_preload) {
+#if defined(__BIONIC__)
+ std::string helper = get_testlib_root() +
+ "/ld_config_test_helper/ld_config_test_helper";
+ std::string config_file = get_testlib_root() + "/ld.config.txt";
+ create_ld_config_file(config_file);
+ std::string env = std::string("LD_CONFIG_FILE=") + config_file;
+ std::string env2 = std::string("LD_PRELOAD=") + get_testlib_root() + "/ld_config_test_helper_lib3.so";
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({ helper.c_str(), nullptr });
+ eth.SetEnv({ env.c_str(), env2.c_str(), nullptr });
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "54321");
+#endif
+}
+
+#endif // USE_LD_CONFIG_FILE
+
+// ensures that LD_CONFIG_FILE env var does not work for production builds.
+// The test input is the same as exec_with_ld_config_file, but it must fail in
+// this case.
+TEST(dl, disable_ld_config_file) {
+#if defined(__BIONIC__)
+ if (getuid() == 0) {
+ // when executed from the shell (e.g. not as part of CTS), skip the test.
+ // This test is only for CTS.
+ return;
+ }
+ std::string error_message = "CANNOT LINK EXECUTABLE \"" + get_testlib_root() + "/ld_config_test_helper/ld_config_test_helper\": library \"ld_config_test_helper_lib1.so\" not found\n";
+ std::string helper = get_testlib_root() +
+ "/ld_config_test_helper/ld_config_test_helper";
+ std::string config_file = get_testlib_root() + "/ld.config.txt";
+ create_ld_config_file(config_file);
+ std::string env = std::string("LD_CONFIG_FILE=") + config_file;
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({ helper.c_str(), nullptr });
+ eth.SetEnv({ env.c_str(), nullptr });
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, -6, error_message.c_str());
+#endif
+}
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 4901d50..1e2b6c9 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1271,6 +1271,37 @@
dlclose(handle);
}
+TEST(dlfcn, dt_runpath_absolute_path) {
+ std::string libpath = get_testlib_root() + "/libtest_dt_runpath_d.so";
+ void* handle = dlopen(libpath.c_str(), RTLD_NOW);
+ ASSERT_TRUE(handle != nullptr) << dlerror();
+
+ typedef void *(* dlopen_b_fn)();
+ dlopen_b_fn fn = (dlopen_b_fn)dlsym(handle, "dlopen_b");
+ ASSERT_TRUE(fn != nullptr) << dlerror();
+
+ void *p = fn();
+ ASSERT_TRUE(p != nullptr);
+
+ dlclose(handle);
+}
+
+TEST(dlfcn, RTLD_macros) {
+#if !defined(RTLD_LOCAL)
+#error no RTLD_LOCAL
+#elif !defined(RTLD_LAZY)
+#error no RTLD_LAZY
+#elif !defined(RTLD_NOW)
+#error no RTLD_NOW
+#elif !defined(RTLD_NOLOAD)
+#error no RTLD_NOLOAD
+#elif !defined(RTLD_GLOBAL)
+#error no RTLD_GLOBAL
+#elif !defined(RTLD_NODELETE)
+#error no RTLD_NODELETE
+#endif
+}
+
// Bionic specific tests
#if defined(__BIONIC__)
@@ -1352,21 +1383,6 @@
#endif // defined(__arm__)
-TEST(dlfcn, dt_runpath_absolute_path) {
- std::string libpath = get_testlib_root() + "/libtest_dt_runpath_d.so";
- void* handle = dlopen(libpath.c_str(), RTLD_NOW);
- ASSERT_TRUE(handle != nullptr) << dlerror();
-
- typedef void *(* dlopen_b_fn)();
- dlopen_b_fn fn = (dlopen_b_fn)dlsym(handle, "dlopen_b");
- ASSERT_TRUE(fn != nullptr) << dlerror();
-
- void *p = fn();
- ASSERT_TRUE(p != nullptr);
-
- dlclose(handle);
-}
-
TEST(dlfcn, dlopen_invalid_rw_load_segment) {
const std::string libpath = get_testlib_root() +
"/" + kPrebuiltElfDir +
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/tests/errno_test.cpp
similarity index 62%
copy from libc/arch-arm/include/machine/cpu-features.h
copy to tests/errno_test.cpp
index fc8c80d..ae4ce08 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/tests/errno_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,24 +25,10 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef _ARM_MACHINE_CPU_FEATURES_H
-#define _ARM_MACHINE_CPU_FEATURES_H
-/* __ARM_ARCH__ is a number corresponding to the ARM revision
- * we're going to support. Our toolchain doesn't define __ARM_ARCH__
- * so try to guess it.
- */
-#ifndef __ARM_ARCH__
-# if defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ || \
- defined __ARM_ARCH_7R__ || defined __ARM_ARCH_7M__
-# define __ARM_ARCH__ 7
-# elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ || \
- defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6Z__ || \
- defined __ARM_ARCH_6KZ__ || defined __ARM_ARCH_6T2__
-# define __ARM_ARCH__ 6
-# else
-# error Unknown or unsupported ARM architecture
-# endif
-#endif
+#include <gtest/gtest.h>
-#endif /* _ARM_MACHINE_CPU_FEATURES_H */
+#include <errno.h>
+
+// Some GNU source likes to declare errno itself for some reason.
+extern "C" int errno;
diff --git a/tests/fcntl_test.cpp b/tests/fcntl_test.cpp
index 74d3675..f385311 100644
--- a/tests/fcntl_test.cpp
+++ b/tests/fcntl_test.cpp
@@ -279,9 +279,10 @@
}
/*
- * Kernels less than 4.1 are affected.
- * Devices that fail this test should include change id from Nexus:
- * Commit: 9b431291a1fadbdbcca1485711b5bab145112293
+ * b/28760453:
+ * Kernels older than 4.1 should have ext4 FALLOC_FL_PUNCH_HOLE disabled due to CVE-2015-8839.
+ * Devices that fail this test should cherry-pick the following commit:
+ * https://android.googlesource.com/kernel/msm/+/bdba352e898cbf57c8620ad68c8abf749c784d1f
*/
TEST(fcntl, falloc_punch) {
long major = 0, minor = 0;
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index 973a8d2..c1600cc 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -617,3 +617,59 @@
defaults: ["bionic_testlib_defaults"],
srcs: ["preinit_syscall_test_helper.cpp"],
}
+
+cc_test {
+ name: "ld_preload_test_helper",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_preload_test_helper.cpp"],
+ shared_libs: ["ld_preload_test_helper_lib1"],
+ ldflags: ["-Wl,--rpath,${ORIGIN}/.."],
+}
+
+cc_test_library {
+ name: "ld_preload_test_helper_lib1",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_preload_test_helper_lib1.cpp"],
+}
+
+cc_test_library {
+ name: "ld_preload_test_helper_lib2",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_preload_test_helper_lib2.cpp"],
+}
+
+cc_test {
+ name: "ld_config_test_helper",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_config_test_helper.cpp"],
+ shared_libs: ["ld_config_test_helper_lib1"],
+ ldflags: ["-Wl,--rpath,${ORIGIN}/.."],
+}
+
+cc_test_library {
+ name: "ld_config_test_helper_lib1",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_config_test_helper_lib1.cpp"],
+ shared_libs: ["ld_config_test_helper_lib2"],
+ relative_install_path: "/ns2",
+}
+
+cc_test_library {
+ name: "ld_config_test_helper_lib2",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_config_test_helper_lib2.cpp"],
+ relative_install_path: "/ns2",
+}
+
+cc_test_library {
+ name: "ld_config_test_helper_lib3",
+ host_supported: false,
+ defaults: ["bionic_testlib_defaults"],
+ srcs: ["ld_config_test_helper_lib3.cpp"],
+}
diff --git a/tests/libs/ld_config_test_helper.cpp b/tests/libs/ld_config_test_helper.cpp
new file mode 100644
index 0000000..592e8c0
--- /dev/null
+++ b/tests/libs/ld_config_test_helper.cpp
@@ -0,0 +1,26 @@
+/*
+ * 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 <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+extern int get_value_from_lib();
+
+int main() {
+ printf("%d", get_value_from_lib());
+ return 0;
+}
diff --git a/tests/libs/ld_config_test_helper_lib1.cpp b/tests/libs/ld_config_test_helper_lib1.cpp
new file mode 100644
index 0000000..fc5401a
--- /dev/null
+++ b/tests/libs/ld_config_test_helper_lib1.cpp
@@ -0,0 +1,4 @@
+extern int get_value_from_another_lib();
+int get_value_from_lib() {
+ return get_value_from_another_lib();
+}
diff --git a/tests/libs/ld_config_test_helper_lib2.cpp b/tests/libs/ld_config_test_helper_lib2.cpp
new file mode 100644
index 0000000..a620a6c
--- /dev/null
+++ b/tests/libs/ld_config_test_helper_lib2.cpp
@@ -0,0 +1,3 @@
+int get_value_from_another_lib() {
+ return 12345;
+}
diff --git a/tests/libs/ld_config_test_helper_lib3.cpp b/tests/libs/ld_config_test_helper_lib3.cpp
new file mode 100644
index 0000000..93d1cd8
--- /dev/null
+++ b/tests/libs/ld_config_test_helper_lib3.cpp
@@ -0,0 +1,3 @@
+int get_value_from_another_lib() {
+ return 54321;
+}
diff --git a/tests/libs/ld_preload_test_helper.cpp b/tests/libs/ld_preload_test_helper.cpp
new file mode 100644
index 0000000..592e8c0
--- /dev/null
+++ b/tests/libs/ld_preload_test_helper.cpp
@@ -0,0 +1,26 @@
+/*
+ * 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 <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+extern int get_value_from_lib();
+
+int main() {
+ printf("%d", get_value_from_lib());
+ return 0;
+}
diff --git a/tests/libs/ld_preload_test_helper_lib1.cpp b/tests/libs/ld_preload_test_helper_lib1.cpp
new file mode 100644
index 0000000..74e89db
--- /dev/null
+++ b/tests/libs/ld_preload_test_helper_lib1.cpp
@@ -0,0 +1,3 @@
+int get_value_from_lib() {
+ return 12345;
+}
diff --git a/tests/libs/ld_preload_test_helper_lib2.cpp b/tests/libs/ld_preload_test_helper_lib2.cpp
new file mode 100644
index 0000000..9239891
--- /dev/null
+++ b/tests/libs/ld_preload_test_helper_lib2.cpp
@@ -0,0 +1,3 @@
+int get_value_from_lib() {
+ return 54321;
+}
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index a7b9d52..ddd78b0 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -100,16 +100,6 @@
}
}
-TEST(malloc, posix_memalign_non_power2) {
- void* ptr;
- ASSERT_EQ(EINVAL, posix_memalign(&ptr, 17, 1024));
-}
-
-TEST(malloc, posix_memalign_overflow) {
- void* ptr;
- ASSERT_NE(0, posix_memalign(&ptr, 16, SIZE_MAX));
-}
-
TEST(malloc, memalign_realloc) {
// Memalign and then realloc the pointer a couple of times.
for (size_t alignment = 1; alignment <= 4096; alignment <<= 1) {
diff --git a/tests/qsort_test.cpp b/tests/qsort_test.cpp
new file mode 100644
index 0000000..95b4789
--- /dev/null
+++ b/tests/qsort_test.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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 <stdlib.h>
+#include <sys/types.h>
+
+#include <gtest/gtest.h>
+
+#include "gtest_globals.h"
+
+#define BUFFER_SIZE 1024
+
+static int cmp_long(const void *l, const void *r)
+{
+
+ return (*(long *)l - *(long *)r);
+}
+
+static int cmp_int(const void *l, const void *r)
+{
+
+ return (*(int *)l - *(int *)r);
+}
+
+#ifndef arc4random_uniform
+static bool seeded;
+
+u_int32_t arc4random_uniform(uint32_t upper_bound)
+{
+ if (!seeded) {
+ srandom((int)time(NULL));
+ seeded = true;
+ }
+
+ return (random() % upper_bound);
+}
+#endif
+
+TEST(qsort_test, long_test) {
+ long buf[BUFFER_SIZE];
+ long i;
+
+ /* Initialize buffer with known numbers */
+ for (i=0; i<BUFFER_SIZE; i++)
+ buf[i] = i;
+
+ /* Stir 1/4 pairs in the buffer */
+ for (i=0; i<BUFFER_SIZE/4; i++) {
+ u_int32_t pos1, pos2;
+ long t;
+
+ pos1 = arc4random_uniform(BUFFER_SIZE);
+ pos2 = arc4random_uniform(BUFFER_SIZE);
+
+ t = buf[pos1];
+ buf[pos1] = buf[pos2];
+ buf[pos2] = t;
+ }
+
+ /* Sort */
+ qsort(buf, BUFFER_SIZE, sizeof(buf[0]), &cmp_long);
+
+ for (i=0; i<BUFFER_SIZE; i++)
+ EXPECT_EQ(i, buf[i]);
+}
+
+TEST(qsort_test, int_test) {
+ int buf[BUFFER_SIZE];
+ int i;
+
+ /* Initialize buffer with known numbers */
+ for (i=0; i<BUFFER_SIZE; i++)
+ buf[i] = i;
+
+ /* Stir 1/4 pairs in the buffer */
+ for (i=0; i<BUFFER_SIZE/4; i++) {
+ u_int32_t pos1, pos2;
+ int t;
+
+ pos1 = arc4random_uniform(BUFFER_SIZE);
+ pos2 = arc4random_uniform(BUFFER_SIZE);
+
+ t = buf[pos1];
+ buf[pos1] = buf[pos2];
+ buf[pos2] = t;
+ }
+
+ /* Sort */
+ qsort(buf, BUFFER_SIZE, sizeof(buf[0]), &cmp_int);
+
+ for (i=0; i<BUFFER_SIZE; i++)
+ EXPECT_EQ(i, buf[i]);
+}
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index fc17cde..4c4c102 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -138,15 +138,48 @@
EXPECT_EQ(795539493, mrand48());
}
-TEST(stdlib, posix_memalign) {
- void* p;
+TEST(stdlib, posix_memalign_sweep) {
+ void* ptr;
- ASSERT_EQ(0, posix_memalign(&p, 512, 128));
- ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(p) % 512);
- free(p);
+ // These should all fail.
+ for (size_t align = 0; align < sizeof(long); align++) {
+ ASSERT_EQ(EINVAL, posix_memalign(&ptr, align, 256))
+ << "Unexpected value at align " << align;
+ }
- // Can't align to a non-power of 2.
- ASSERT_EQ(EINVAL, posix_memalign(&p, 81, 128));
+ // Verify powers of 2 up to 2048 allocate, and verify that all other
+ // alignment values between the powers of 2 fail.
+ size_t last_align = sizeof(long);
+ for (size_t align = sizeof(long); align <= 2048; align <<= 1) {
+ // Try all of the non power of 2 values from the last until this value.
+ for (size_t fail_align = last_align + 1; fail_align < align; fail_align++) {
+ ASSERT_EQ(EINVAL, posix_memalign(&ptr, fail_align, 256))
+ << "Unexpected success at align " << fail_align;
+ }
+ ASSERT_EQ(0, posix_memalign(&ptr, align, 256))
+ << "Unexpected failure at align " << align;
+ ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) & (align - 1))
+ << "Did not return a valid aligned ptr " << ptr << " expected alignment " << align;
+ free(ptr);
+ last_align = align;
+ }
+}
+
+TEST(stdlib, posix_memalign_various_sizes) {
+ std::vector<size_t> sizes{1, 4, 8, 256, 1024, 65000, 128000, 256000, 1000000};
+ for (auto size : sizes) {
+ void* ptr;
+ ASSERT_EQ(0, posix_memalign(&ptr, 16, 1))
+ << "posix_memalign failed at size " << size;
+ ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) & 0xf)
+ << "Pointer not aligned at size " << size << " ptr " << ptr;
+ free(ptr);
+ }
+}
+
+TEST(stdlib, posix_memalign_overflow) {
+ void* ptr;
+ ASSERT_NE(0, posix_memalign(&ptr, 16, SIZE_MAX));
}
TEST(stdlib, realpath__NULL_filename) {
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/sys_ttydefaults_test.cpp b/tests/sys_ttydefaults_test.cpp
new file mode 100644
index 0000000..fa4f7c7
--- /dev/null
+++ b/tests/sys_ttydefaults_test.cpp
@@ -0,0 +1,33 @@
+/*
+ * 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 <sys/ttydefaults.h>
+#include <termios.h>
+
+TEST(sys_ttydefaults, flags) {
+ int i;
+ i = TTYDEF_IFLAG;
+ i = TTYDEF_OFLAG;
+ i = TTYDEF_LFLAG;
+ i = TTYDEF_CFLAG;
+ i = TTYDEF_SPEED;
+}
+
+TEST(sys_ttydefaults, correct_CEOL) {
+ ASSERT_EQ(_POSIX_VDISABLE, CEOL);
+}
diff --git a/tests/uchar_test.cpp b/tests/uchar_test.cpp
index c887f8a..8b29667 100644
--- a/tests/uchar_test.cpp
+++ b/tests/uchar_test.cpp
@@ -280,7 +280,10 @@
char bytes[MB_LEN_MAX];
+ memset(bytes, 1, sizeof(bytes));
EXPECT_EQ(1U, c32rtomb(bytes, L'\0', NULL));
+ EXPECT_EQ('\0', bytes[0]);
+ EXPECT_EQ('\x01', bytes[1]);
memset(bytes, 0, sizeof(bytes));
EXPECT_EQ(1U, c32rtomb(bytes, L'h', NULL));
@@ -408,4 +411,3 @@
GTEST_LOG_(INFO) << "uchar.h is unavailable.\n";
#endif
}
-
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 9a80409..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);
@@ -774,12 +775,6 @@
EXPECT_GT(_XOPEN_IOV_MAX, 0);
EXPECT_GT(_XOPEN_UNIX, 0);
- // In O, the headers still have -1 (even though all the functionality has
- // been there for a long time). This was fixed in O-DR, but there isn't a
- // separate CTS for O-DR, so we'll accept both.
- EXPECT_TRUE(_POSIX_THREAD_PROCESS_SHARED == -1 ||
- _POSIX_THREAD_PROCESS_SHARED == _POSIX_VERSION);
-
#if defined(__BIONIC__)
// These tests only pass on bionic, as bionic and glibc has different support on these macros.
// Macros like _POSIX_ASYNCHRONOUS_IO are not supported on bionic yet.
@@ -790,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/tests/wchar_test.cpp b/tests/wchar_test.cpp
index 830eb70..097647f 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -445,6 +445,18 @@
ASSERT_EQ(L'e', dst[1]);
ASSERT_EQ(L'l', dst[2]);
ASSERT_EQ(&s[3], src);
+
+ memset(dst, 0, sizeof(dst));
+ const char* incomplete = "\xc2"; // Incomplete UTF-8 sequence.
+ src = incomplete;
+ errno = 0;
+ ASSERT_EQ(static_cast<size_t>(-1), mbsnrtowcs(dst, &src, SIZE_MAX, 3, nullptr));
+ ASSERT_EQ(EILSEQ, errno);
+
+ src = incomplete;
+ errno = 0;
+ ASSERT_EQ(static_cast<size_t>(-1), mbsnrtowcs(nullptr, &src, SIZE_MAX, 3, nullptr));
+ ASSERT_EQ(EILSEQ, errno);
}
TEST(wchar, wcsftime) {
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_);