Merge "libc: Fix mktime returns an uncorrect time in empty TZ case"
diff --git a/libc/Android.mk b/libc/Android.mk
index 7d438f4..3e37ca7 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -548,13 +548,6 @@
   libc_common_cflags += -DMALLOC_ALIGNMENT=$(BOARD_MALLOC_ALIGNMENT)
 endif
 
-# Define ANDROID_SMP appropriately.
-ifeq ($(TARGET_CPU_SMP),true)
-    libc_common_cflags += -DANDROID_SMP=1
-else
-    libc_common_cflags += -DANDROID_SMP=0
-endif
-
 # Define some common conlyflags
 libc_common_conlyflags := \
     -std=gnu99
diff --git a/libc/private/bionic_atomic_arm.h b/libc/private/bionic_atomic_arm.h
index 2156e6a..0cb832f 100644
--- a/libc/private/bionic_atomic_arm.h
+++ b/libc/private/bionic_atomic_arm.h
@@ -17,12 +17,7 @@
 #define BIONIC_ATOMIC_ARM_H
 
 __ATOMIC_INLINE__ void __bionic_memory_barrier() {
-#if defined(ANDROID_SMP) && ANDROID_SMP == 1
   __asm__ __volatile__ ( "dmb ish" : : : "memory" );
-#else
-  /* A simple compiler barrier. */
-  __asm__ __volatile__ ( "" : : : "memory" );
-#endif
 }
 
 /* Compare-and-swap, without any explicit barriers. Note that this function
diff --git a/libc/private/bionic_atomic_inline.h b/libc/private/bionic_atomic_inline.h
index b834a27..f8032c3 100644
--- a/libc/private/bionic_atomic_inline.h
+++ b/libc/private/bionic_atomic_inline.h
@@ -30,10 +30,6 @@
  *   on SMP systems emits an appropriate instruction.
  */
 
-#if !defined(ANDROID_SMP)
-# error "Must define ANDROID_SMP before including atomic-inline.h"
-#endif
-
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/libc/private/bionic_atomic_mips.h b/libc/private/bionic_atomic_mips.h
index 5e08116..83f75fe 100644
--- a/libc/private/bionic_atomic_mips.h
+++ b/libc/private/bionic_atomic_mips.h
@@ -21,12 +21,7 @@
  */
 
 __ATOMIC_INLINE__ void __bionic_memory_barrier() {
-#if defined(ANDROID_SMP) && ANDROID_SMP == 1
   __asm__ __volatile__ ( "sync" : : : "memory" );
-#else
-  /* A simple compiler barrier. */
-  __asm__ __volatile__ ( "" : : : "memory" );
-#endif
 }
 
 /* Compare-and-swap, without any explicit barriers. Note that this function
diff --git a/libc/private/bionic_atomic_x86.h b/libc/private/bionic_atomic_x86.h
index 89639c8..e63df93 100644
--- a/libc/private/bionic_atomic_x86.h
+++ b/libc/private/bionic_atomic_x86.h
@@ -20,12 +20,7 @@
  * platform for a multi-core device.
  */
 __ATOMIC_INLINE__ void __bionic_memory_barrier() {
-#if defined(ANDROID_SMP) && ANDROID_SMP == 1
   __asm__ __volatile__ ( "mfence" : : : "memory" );
-#else
-  /* A simple compiler barrier. */
-  __asm__ __volatile__ ( "" : : : "memory" );
-#endif
 }
 
 /* Compare-and-swap, without any explicit barriers. Note that this function
diff --git a/tests/Android.build.mk b/tests/Android.build.mk
index 9c5df0e..0754a7b 100644
--- a/tests/Android.build.mk
+++ b/tests/Android.build.mk
@@ -35,7 +35,10 @@
 endif
 
 LOCAL_CLANG := $($(module)_clang_$(build_type))
+
+ifneq ($($(module)_allow_asan),true)
 LOCAL_ADDRESS_SANITIZER := false
+endif
 
 LOCAL_FORCE_STATIC_EXECUTABLE := $($(module)_force_static_executable)
 
diff --git a/tests/Android.mk b/tests/Android.mk
index 967ddbd..92d7976 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -317,6 +317,8 @@
 bionic-unit-tests-glibc_cppflags := $(test_cppflags)
 bionic-unit-tests-glibc_ldflags := -Wl,--export-dynamic
 
+bionic-unit-tests-glibc_allow_asan := true
+
 module := bionic-unit-tests-glibc
 module_tag := optional
 build_type := host
diff --git a/tests/netdb_test.cpp b/tests/netdb_test.cpp
index ef2c8da..0cebe4e 100644
--- a/tests/netdb_test.cpp
+++ b/tests/netdb_test.cpp
@@ -21,6 +21,23 @@
 #include <netdb.h>
 #include <netinet/in.h>
 
+TEST(netdb, getaddrinfo_NULL_host) {
+  // It's okay for the host argument to be NULL, as long as service isn't.
+  addrinfo* ai = NULL;
+  ASSERT_EQ(0, getaddrinfo(NULL, "smtp", NULL, &ai));
+  // (sockaddr_in::sin_port and sockaddr_in6::sin6_port overlap.)
+  ASSERT_EQ(25U, ntohs(reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_port));
+  freeaddrinfo(ai);
+}
+
+TEST(netdb, getaddrinfo_NULL_service) {
+  // It's okay for the service argument to be NULL, as long as host isn't.
+  addrinfo* ai = NULL;
+  ASSERT_EQ(0, getaddrinfo("localhost", NULL, NULL, &ai));
+  ASSERT_TRUE(ai != NULL);
+  freeaddrinfo(ai);
+}
+
 TEST(netdb, getaddrinfo_NULL_hints) {
   addrinfo* ai = NULL;
   ASSERT_EQ(0, getaddrinfo("localhost", "9999", NULL, &ai));
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index b5fcf26..50afd05 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -30,10 +30,6 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
-TEST(unistd, sysconf_SC_MONOTONIC_CLOCK) {
-  ASSERT_GT(sysconf(_SC_MONOTONIC_CLOCK), 0);
-}
-
 static void* get_brk() {
   return sbrk(0);
 }
@@ -520,3 +516,138 @@
   rc = fpathconf(tf.fd, _PC_REC_XFER_ALIGN);
   ASSERT_TRUE(rc > 0 && powerof2(rc));
 }
+
+#define verifySysconf(name, ret) \
+{\
+  errno = 0;\
+  ret = sysconf(name);\
+  ASSERT_TRUE((0 == errno) && (-1 != ret)) << "name=" << #name << ", ret=" << ret << ", Error Message: " << strerror(errno);\
+}\
+
+TEST(unistd, sysconf) {
+  long ret;
+
+  verifySysconf(_SC_MONOTONIC_CLOCK, ret);
+  ASSERT_GT(ret, 0);
+  verifySysconf(_SC_ARG_MAX, ret);
+  ASSERT_GT(ret, 0);
+  verifySysconf(_SC_CHILD_MAX, ret);
+  ASSERT_GT(ret, 0);
+  verifySysconf(_SC_CLK_TCK, ret);
+  ASSERT_GT(ret, 0);
+  verifySysconf(_SC_LINE_MAX, ret);
+  ASSERT_GT(ret, 1);
+  verifySysconf(_SC_NGROUPS_MAX, ret);
+  ASSERT_GT(ret, 0);
+  verifySysconf(_SC_OPEN_MAX, ret);
+  ASSERT_GT(ret, 1);
+  verifySysconf(_SC_2_C_BIND, ret);
+  ASSERT_GT(ret, 0);
+  verifySysconf(_SC_2_C_VERSION, ret);
+  verifySysconf(_SC_JOB_CONTROL, ret);
+  ASSERT_EQ(1, ret);
+  verifySysconf(_SC_SAVED_IDS, ret);
+  ASSERT_EQ(1, ret);
+  verifySysconf(_SC_VERSION, ret);
+  verifySysconf(_SC_RE_DUP_MAX, ret);
+  verifySysconf(_SC_STREAM_MAX, ret);
+  ASSERT_GT(ret, 0);
+  verifySysconf(_SC_TZNAME_MAX, ret);
+  verifySysconf(_SC_XOPEN_VERSION, ret);
+  verifySysconf(_SC_ATEXIT_MAX, ret);
+  ASSERT_GT(ret, 1);
+  verifySysconf(_SC_IOV_MAX, ret);
+  ASSERT_GT(ret, 0);
+  verifySysconf(_SC_PAGESIZE, ret);
+  ASSERT_GE(ret, 1);
+  verifySysconf(_SC_PAGE_SIZE, ret);
+  ASSERT_GE(ret, 1);
+  verifySysconf(_SC_XOPEN_UNIX, ret);
+  verifySysconf(_SC_DELAYTIMER_MAX, ret);
+  ASSERT_GT(ret, 0);
+  verifySysconf(_SC_MQ_OPEN_MAX, ret);
+  verifySysconf(_SC_MQ_PRIO_MAX, ret);
+  ASSERT_GT(ret ,0);
+  verifySysconf(_SC_RTSIG_MAX, ret);
+  verifySysconf(_SC_SEM_NSEMS_MAX, ret);
+  verifySysconf(_SC_SEM_VALUE_MAX, ret);
+  verifySysconf(_SC_SIGQUEUE_MAX, ret);
+  ASSERT_GT(ret, 0);
+  verifySysconf(_SC_TIMER_MAX, ret);
+  verifySysconf(_SC_FSYNC, ret);
+  verifySysconf(_SC_MAPPED_FILES, ret);
+  verifySysconf(_SC_PRIORITY_SCHEDULING, ret);
+  verifySysconf(_SC_SEMAPHORES, ret);
+  verifySysconf(_SC_SYNCHRONIZED_IO, ret);
+  verifySysconf(_SC_TIMERS, ret);
+  verifySysconf(_SC_GETGR_R_SIZE_MAX, ret);
+  verifySysconf(_SC_GETPW_R_SIZE_MAX, ret);
+  verifySysconf(_SC_LOGIN_NAME_MAX, ret);
+  verifySysconf(_SC_THREAD_DESTRUCTOR_ITERATIONS, ret);
+  verifySysconf(_SC_THREAD_KEYS_MAX, ret);
+  verifySysconf(_SC_THREAD_STACK_MIN, ret);
+  verifySysconf(_SC_THREAD_THREADS_MAX, ret);
+  verifySysconf(_SC_TTY_NAME_MAX, ret);
+  ASSERT_GT(ret, 0);
+  verifySysconf(_SC_THREADS, ret);
+  verifySysconf(_SC_THREAD_PRIO_INHERIT, ret);
+  verifySysconf(_SC_THREAD_PRIO_PROTECT, ret);
+  verifySysconf(_SC_NPROCESSORS_CONF, ret);
+  verifySysconf(_SC_NPROCESSORS_ONLN, ret);
+  verifySysconf(_SC_PHYS_PAGES, ret);
+  verifySysconf(_SC_AVPHYS_PAGES, ret);
+
+  //  TODO: keep following names check here
+  //  so that we can enable them when the error fixed
+
+  /* when call sysconf with following name,
+     the system call will report error "Function not implemented"
+
+  verifySysconf(_SC_BC_BASE_MAX, ret);
+  verifySysconf(_SC_BC_DIM_MAX, ret);
+  verifySysconf(_SC_BC_SCALE_MAX, ret);
+  verifySysconf(_SC_BC_STRING_MAX, ret);
+  verifySysconf(_SC_COLL_WEIGHTS_MAX, ret);
+  verifySysconf(_SC_EXPR_NEST_MAX, ret);
+  verifySysconf(_SC_XOPEN_SHM, ret);
+  verifySysconf(_SC_XBS5_ILP32_OFF32, ret);
+  verifySysconf(_SC_XBS5_ILP32_OFFBIG, ret);
+  verifySysconf(_SC_XBS5_LP64_OFF64, ret);
+  verifySysconf(_SC_XBS5_LPBIG_OFFBIG, ret);
+  verifySysconf(_SC_AIO_LISTIO_MAX, ret);
+  verifySysconf(_SC_AIO_MAX, ret);
+  verifySysconf(_SC_AIO_PRIO_DELTA_MAX, ret);
+  verifySysconf(_SC_ASYNCHRONOUS_IO, ret);
+  verifySysconf(_SC_MEMLOCK, ret);
+  verifySysconf(_SC_MEMLOCK_RANGE, ret);
+  verifySysconf(_SC_MEMORY_PROTECTION, ret);
+  verifySysconf(_SC_MESSAGE_PASSING, ret);
+  verifySysconf(_SC_PRIORITIZED_IO, ret);
+  verifySysconf(_SC_SHARED_MEMORY_OBJECTS, ret);
+  verifySysconf(_SC_THREAD_SAFE_FUNCTIONS, ret);
+
+  */
+
+  /* when following names are checked,
+     the return value of sysconf is -1,
+     which means following name are invalid.
+
+  verifySysconf(_SC_2_C_DEV, ret);
+  verifySysconf(_SC_2_FORT_DEV, ret);
+  verifySysconf(_SC_2_FORT_RUN, ret);
+  verifySysconf(_SC_2_LOCALEDEF, ret);
+  verifySysconf(_SC_2_SW_DEV, ret);
+  verifySysconf(_SC_2_UPE, ret);
+  verifySysconf(_SC_2_VERSION, ret);
+  verifySysconf(_SC_XOPEN_CRYPT, ret);
+  verifySysconf(_SC_XOPEN_ENH_I18N, ret);
+  verifySysconf(_SC_XOPEN_XCU_VERSION, ret);
+  verifySysconf(_SC_XOPEN_REALTIME, ret);
+  verifySysconf(_SC_XOPEN_REALTIME_THREADS, ret);
+  verifySysconf(_SC_XOPEN_LEGACY, ret);
+  verifySysconf(_SC_THREAD_ATTR_STACKADDR, ret);
+  verifySysconf(_SC_THREAD_ATTR_STACKSIZE, ret);
+  verifySysconf(_SC_REALTIME_SIGNALS, ret);
+
+  */
+}