Merge "Whitelist __NR__newselect."
diff --git a/benchmarks/string_benchmark.cpp b/benchmarks/string_benchmark.cpp
index 41306db..86a7c35 100644
--- a/benchmarks/string_benchmark.cpp
+++ b/benchmarks/string_benchmark.cpp
@@ -58,19 +58,42 @@
}
BENCHMARK(BM_string_memcpy)->AT_COMMON_SIZES;
-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);
+ std::vector<char> src(nbytes, 'x');
+ std::vector<char> dst(nbytes, 'x');
while (state.KeepRunning()) {
- memmove(buf, buf + 1, nbytes); // Worst-case overlap.
+ memmove(dst.data(), src.data(), 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_COMMON_SIZES;
+
+static void BM_string_memmove_overlap_dst_before_src(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+ std::vector<char> buf(nbytes + 1, 'x');
+
+ while (state.KeepRunning()) {
+ memmove(buf.data(), buf.data() + 1, nbytes); // Worst-case overlap.
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BENCHMARK(BM_string_memmove_overlap_dst_before_src)->AT_COMMON_SIZES;
+
+static void BM_string_memmove_overlap_src_before_dst(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+ std::vector<char> buf(nbytes + 1, 'x');
+
+ while (state.KeepRunning()) {
+ memmove(buf.data() + 1, buf.data(), nbytes); // Worst-case overlap.
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BENCHMARK(BM_string_memmove_overlap_src_before_dst)->AT_COMMON_SIZES;
static void BM_string_memset(benchmark::State& state) {
const size_t nbytes = state.range(0);
@@ -100,3 +123,83 @@
delete[] s;
}
BENCHMARK(BM_string_strlen)->AT_COMMON_SIZES;
+
+static void BM_string_strcat_copy_only(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+ std::vector<char> src(nbytes, 'x');
+ std::vector<char> dst(nbytes + 2);
+ src[nbytes - 1] = '\0';
+ dst[0] = 'y';
+ dst[1] = 'y';
+ dst[2] = '\0';
+
+ while (state.KeepRunning()) {
+ strcat(dst.data(), src.data());
+ dst[2] = '\0';
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BENCHMARK(BM_string_strcat_copy_only)->AT_COMMON_SIZES;
+
+static void BM_string_strcat_seek_only(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+ std::vector<char> src(3, 'x');
+ std::vector<char> dst(nbytes + 2, 'y');
+ src[2] = '\0';
+ dst[nbytes - 1] = '\0';
+
+ while (state.KeepRunning()) {
+ strcat(dst.data(), src.data());
+ dst[nbytes - 1] = '\0';
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BENCHMARK(BM_string_strcat_seek_only)->AT_COMMON_SIZES;
+
+static void BM_string_strcat_half_copy_half_seek(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+ std::vector<char> src(nbytes / 2, 'x');
+ std::vector<char> dst(nbytes / 2, 'y');
+ src[nbytes / 2 - 1] = '\0';
+ dst[nbytes / 2 - 1] = '\0';
+
+ while (state.KeepRunning()) {
+ strcat(dst.data(), src.data());
+ dst[nbytes / 2 - 1] = '\0';
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BENCHMARK(BM_string_strcat_half_copy_half_seek)->AT_COMMON_SIZES;
+
+static void BM_string_strcpy(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+ std::vector<char> src(nbytes, 'x');
+ std::vector<char> dst(nbytes);
+ src[nbytes - 1] = '\0';
+
+ while (state.KeepRunning()) {
+ strcpy(dst.data(), src.data());
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BENCHMARK(BM_string_strcpy)->AT_COMMON_SIZES;
+
+static void BM_string_strcmp(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+ std::vector<char> s1(nbytes, 'x');
+ std::vector<char> s2(nbytes, 'x');
+ s1[nbytes - 1] = '\0';
+ s2[nbytes - 1] = '\0';
+
+ volatile int c __attribute__((unused));
+ while (state.KeepRunning()) {
+ c = strcmp(s1.data(), s2.data());
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BENCHMARK(BM_string_strcmp)->AT_COMMON_SIZES;
diff --git a/libc/Android.bp b/libc/Android.bp
index 5a1c287..4f6ff1a 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
@@ -1757,10 +1763,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..82df90a 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.
diff --git a/libc/SECCOMP_WHITELIST.TXT b/libc/SECCOMP_WHITELIST.TXT
index 4d6897c..11485dd 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/Android.bp b/libc/async_safe/Android.bp
index 9e36d97..a835697 100644
--- a/libc/async_safe/Android.bp
+++ b/libc/async_safe/Android.bp
@@ -8,6 +8,7 @@
],
name: "libasync_safe",
+ vendor_available: true,
include_dirs: ["bionic/libc"],
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/abort.cpp b/libc/bionic/abort.cpp
index 3ba83d1..f401cab 100644
--- a/libc/bionic/abort.cpp
+++ b/libc/bionic/abort.cpp
@@ -32,6 +32,26 @@
#include <sys/syscall.h>
#include <unistd.h>
+// We call tgkill(2) directly instead of raise (or even the libc tgkill wrapper), to reduce the
+// number of uninteresting stack frames at the top of a crash.
+static inline __always_inline void inline_tgkill(pid_t pid, pid_t tid, int sig) {
+#if defined(__arm__)
+ register int r0 __asm__("r0") = pid;
+ register int r1 __asm__("r1") = tid;
+ register int r2 __asm__("r2") = sig;
+ register int r7 __asm__("r7") = __NR_tgkill;
+ __asm__("swi #0" : "=r"(r0) : "r"(r0), "r"(r1), "r"(r2), "r"(r7) : "memory");
+#elif defined(__aarch64__)
+ register long x0 __asm__("x0") = pid;
+ register long x1 __asm__("x1") = tid;
+ register long x2 __asm__("x2") = sig;
+ register long x8 __asm__("x8") = __NR_tgkill;
+ __asm__("svc #0" : "=r"(x0) : "r"(x0), "r"(x1), "r"(x2), "r"(x8) : "memory");
+#else
+ syscall(__NR_tgkill, pid, tid, sig);
+#endif
+}
+
void abort() {
// Protect ourselves against stale cached PID/TID values by fetching them via syscall.
// http://b/37769298
@@ -45,8 +65,7 @@
sigdelset(&mask, SIGABRT);
sigprocmask(SIG_SETMASK, &mask, NULL);
- // Use tgkill directly instead of raise, to avoid inserting spurious stack frames.
- tgkill(pid, tid, SIGABRT);
+ inline_tgkill(pid, tid, SIGABRT);
// If SIGABRT ignored, or caught and the handler returns,
// remove the SIGABRT signal handler and raise SIGABRT again.
@@ -57,7 +76,7 @@
sigaction(SIGABRT, &sa, &sa);
sigprocmask(SIG_SETMASK, &mask, NULL);
- tgkill(pid, tid, SIGABRT);
+ inline_tgkill(pid, tid, SIGABRT);
// If we get this far, just exit.
_exit(127);
diff --git a/libc/bionic/bionic_arc4random.cpp b/libc/bionic/bionic_arc4random.cpp
index a4842f6..a339900 100644
--- a/libc/bionic/bionic_arc4random.cpp
+++ b/libc/bionic/bionic_arc4random.cpp
@@ -32,7 +32,6 @@
#include <stdatomic.h>
#include <stdlib.h>
#include <sys/auxv.h>
-#include <syscall.h>
#include <unistd.h>
#include <async_safe/log.h>
diff --git a/libc/bionic/clone.cpp b/libc/bionic/clone.cpp
index 3a20aa9..d7ce37f 100644
--- a/libc/bionic/clone.cpp
+++ b/libc/bionic/clone.cpp
@@ -30,6 +30,7 @@
#include <sched.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <sys/syscall.h>
#include "pthread_internal.h"
diff --git a/libc/bionic/fork.cpp b/libc/bionic/fork.cpp
index 32ea255..efcbb8c 100644
--- a/libc/bionic/fork.cpp
+++ b/libc/bionic/fork.cpp
@@ -27,7 +27,6 @@
*/
#include <unistd.h>
-#include <sys/syscall.h>
#include "pthread_internal.h"
diff --git a/libc/bionic/gettid.cpp b/libc/bionic/gettid.cpp
index fe25a4d..eb5cfd6 100644
--- a/libc/bionic/gettid.cpp
+++ b/libc/bionic/gettid.cpp
@@ -27,6 +27,7 @@
*/
#include <unistd.h>
+#include <sys/syscall.h>
#include "pthread_internal.h"
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/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/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/pthread.h b/libc/include/pthread.h
index c34d1a3..20b6c5b 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -160,6 +160,18 @@
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
+ * pthread_mutex_timedlock, instead we had pthread_mutex_lock_timeout_np. NDK
+ * users targeting pre-L still need this, but anyone targeting L or newer (or
+ * LP64 code) should just use pthread_mutex_timedlock.
+ *
+ * https://github.com/android-ndk/ndk/issues/420
+ */
+int pthread_mutex_lock_timeout_np(pthread_mutex_t* mutex, unsigned msecs);
+#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/sys/cdefs.h b/libc/include/sys/cdefs.h
index 004c6b5..d62206d 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -303,13 +303,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/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/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/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/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/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/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/linker/tests/linker_config_test.cpp b/linker/tests/linker_config_test.cpp
index 5e51113..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);
diff --git a/tests/Android.bp b/tests/Android.bp
index a03f1a6..2a5b47e 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",
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index e3ee7d7..b264e53 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -30,6 +30,7 @@
#include <linux/memfd.h>
#include <sys/mman.h>
+#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/vfs.h>
#include <sys/wait.h>
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 4901d50..5d3985f 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1271,6 +1271,22 @@
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__)
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/tests/errno_test.cpp
similarity index 62%
rename from libc/arch-arm/include/machine/cpu-features.h
rename 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/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) {