Merge "Test that relro sharing actually saves memory."
diff --git a/libc/Android.mk b/libc/Android.mk
index 4b81f7e..2ec1281 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -568,6 +568,7 @@
 LOCAL_CFLAGS += -DTZDIR=\"/system/usr/share/zoneinfo\"
 # Include timezone and daylight globals.
 LOCAL_CFLAGS += -DUSG_COMPAT=1
+LOCAL_CFLAGS += -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
 
 LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
 LOCAL_CPPFLAGS := $(libc_common_cppflags)
@@ -618,6 +619,7 @@
 LOCAL_SRC_FILES := $(libc_upstream_freebsd_src_files)
 LOCAL_CFLAGS := \
     $(libc_common_cflags) \
+    -Wno-sign-compare -Wno-uninitialized \
     -I$(LOCAL_PATH)/upstream-freebsd/android/include \
     -I$(LOCAL_PATH)/upstream-freebsd/lib/libc/include \
     -include freebsd-compat.h
@@ -644,6 +646,7 @@
 LOCAL_SRC_FILES := $(libc_upstream_netbsd_src_files)
 LOCAL_CFLAGS := \
     $(libc_common_cflags) \
+    -Wno-sign-compare -Wno-uninitialized \
     -DPOSIX_MISTAKE \
     -I$(LOCAL_PATH)/upstream-netbsd/android/include \
     -I$(LOCAL_PATH)/upstream-netbsd/lib/libc/include \
@@ -671,6 +674,7 @@
 LOCAL_SRC_FILES := $(libc_upstream_openbsd_src_files)
 LOCAL_CFLAGS := \
     $(libc_common_cflags) \
+    -Wno-sign-compare -Wno-uninitialized \
     -I$(LOCAL_PATH)/upstream-openbsd/android/include \
     -I$(LOCAL_PATH)/upstream-openbsd/lib/libc/include \
     -I$(LOCAL_PATH)/upstream-openbsd/lib/libc/gdtoa/ \
@@ -699,6 +703,7 @@
 LOCAL_SRC_FILES_64 := $(libc_upstream_openbsd_gdtoa_src_files_64)
 LOCAL_CFLAGS := \
     $(libc_common_cflags) \
+    -Wno-sign-compare -Wno-uninitialized \
     -fvisibility=hidden \
     -I$(LOCAL_PATH)/upstream-openbsd/android/include \
     -I$(LOCAL_PATH)/upstream-openbsd/lib/libc/include \
diff --git a/libc/bionic/libc_logging.cpp b/libc/bionic/libc_logging.cpp
index c9c5d28..f15abbe 100644
--- a/libc/bionic/libc_logging.cpp
+++ b/libc/bionic/libc_logging.cpp
@@ -614,7 +614,7 @@
   __libc_fatal("FORTIFY_SOURCE: %s. Calling abort().", msg);
 }
 
-static void __libc_fatal(const char* tag, const char* format, va_list args) {
+static void __libc_fatal(const char* format, va_list args) {
   char msg[1024];
   BufferOutputStream os(msg, sizeof(msg));
   out_vformat(os, format, args);
@@ -622,50 +622,53 @@
   // TODO: log to stderr for the benefit of "adb shell" users.
 
   // Log to the log for the benefit of regular app developers (whose stdout and stderr are closed).
-  __libc_write_log(ANDROID_LOG_FATAL, tag, msg);
+  __libc_write_log(ANDROID_LOG_FATAL, "libc", msg);
 
-  __libc_set_abort_message(msg);
+  __android_set_abort_message(msg);
 }
 
 void __libc_fatal_no_abort(const char* format, ...) {
   va_list args;
   va_start(args, format);
-  __libc_fatal("libc", format, args);
+  __libc_fatal(format, args);
   va_end(args);
 }
 
 void __libc_fatal(const char* format, ...) {
   va_list args;
   va_start(args, format);
-  __libc_fatal("libc", format, args);
+  __libc_fatal(format, args);
   va_end(args);
   abort();
 }
 
-// This is used by liblog to implement LOG_ALWAYS_FATAL and LOG_ALWAYS_FATAL_IF.
-void __android_fatal(const char* tag, const char* format, ...) {
-  va_list args;
-  va_start(args, format);
-  __libc_fatal(tag, format, args);
-  va_end(args);
-  abort();
-}
+void __android_set_abort_message(const char* msg) {
+  ScopedPthreadMutexLocker locker(&gAbortMsgLock);
 
-void __libc_set_abort_message(const char* msg) {
+  if (__abort_message_ptr == NULL) {
+    // We must have crashed _very_ early.
+    return;
+  }
+
+  if (*__abort_message_ptr != NULL) {
+    // We already have an abort message.
+    // Assume that the first crash is the one most worth reporting.
+    return;
+  }
+
   size_t size = sizeof(abort_msg_t) + strlen(msg) + 1;
   void* map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
   if (map == MAP_FAILED) {
     return;
   }
 
-  if (__abort_message_ptr != NULL) {
-    ScopedPthreadMutexLocker locker(&gAbortMsgLock);
-    if (*__abort_message_ptr != NULL) {
-      munmap(*__abort_message_ptr, (*__abort_message_ptr)->size);
-    }
-    abort_msg_t* new_abort_message = reinterpret_cast<abort_msg_t*>(map);
-    new_abort_message->size = size;
-    strcpy(new_abort_message->msg, msg);
-    *__abort_message_ptr = new_abort_message;
+  // TODO: if we stick to the current "one-shot" scheme, we can remove this code and
+  // stop storing the size.
+  if (*__abort_message_ptr != NULL) {
+    munmap(*__abort_message_ptr, (*__abort_message_ptr)->size);
   }
+  abort_msg_t* new_abort_message = reinterpret_cast<abort_msg_t*>(map);
+  new_abort_message->size = size;
+  strcpy(new_abort_message->msg, msg);
+  *__abort_message_ptr = new_abort_message;
 }
diff --git a/libc/dns/gethnamaddr.c b/libc/dns/gethnamaddr.c
index dbcadee..4da99b2 100644
--- a/libc/dns/gethnamaddr.c
+++ b/libc/dns/gethnamaddr.c
@@ -828,27 +828,27 @@
 
 	assert(addr != NULL);
 
-	if (af == AF_INET6 && len == IN6ADDRSZ &&
-	    (IN6_IS_ADDR_LINKLOCAL((const struct in6_addr *)(const void *)uaddr) ||
-	     IN6_IS_ADDR_SITELOCAL((const struct in6_addr *)(const void *)uaddr))) {
+	if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
+	    (IN6_IS_ADDR_LINKLOCAL((const struct in6_addr *)addr) ||
+	     IN6_IS_ADDR_SITELOCAL((const struct in6_addr *)addr))) {
 		h_errno = HOST_NOT_FOUND;
 		return NULL;
 	}
-	if (af == AF_INET6 && len == IN6ADDRSZ &&
-	    (IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)(const void *)uaddr) ||
-	     IN6_IS_ADDR_V4COMPAT((const struct in6_addr *)(const void *)uaddr))) {
+	if (af == AF_INET6 && len == NS_IN6ADDRSZ &&
+	    (IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)addr) ||
+	     IN6_IS_ADDR_V4COMPAT((const struct in6_addr *)addr))) {
 		/* Unmap. */
-		addr += IN6ADDRSZ - INADDRSZ;
-		uaddr += IN6ADDRSZ - INADDRSZ;
+		uaddr += NS_IN6ADDRSZ - NS_INADDRSZ;
+		addr = uaddr;
 		af = AF_INET;
-		len = INADDRSZ;
+		len = NS_INADDRSZ;
 	}
 	switch (af) {
 	case AF_INET:
-		size = INADDRSZ;
+		size = NS_INADDRSZ;
 		break;
 	case AF_INET6:
-		size = IN6ADDRSZ;
+		size = NS_IN6ADDRSZ;
 		break;
 	default:
 		errno = EAFNOSUPPORT;
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 3f59b91..7b8de81 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -91,7 +91,7 @@
 typedef long pthread_mutexattr_t;
 typedef long pthread_condattr_t;
 
-typedef int pthread_rwlockattr_t;
+typedef long pthread_rwlockattr_t;
 
 typedef struct {
   pthread_mutex_t lock;
diff --git a/libc/include/semaphore.h b/libc/include/semaphore.h
index 30e3123..7ae3c3a 100644
--- a/libc/include/semaphore.h
+++ b/libc/include/semaphore.h
@@ -33,10 +33,13 @@
 __BEGIN_DECLS
 
 typedef struct {
-    volatile unsigned int  count;
+  volatile unsigned int count;
+#ifdef __LP64__
+  int __reserved[3];
+#endif
 } sem_t;
 
-#define  SEM_FAILED  NULL
+#define SEM_FAILED NULL
 
 extern int sem_init(sem_t *sem, int pshared, unsigned int value);
 
diff --git a/libc/include/sys/types.h b/libc/include/sys/types.h
index dc847d2..9a76ad2 100644
--- a/libc/include/sys/types.h
+++ b/libc/include/sys/types.h
@@ -63,7 +63,7 @@
 typedef __kernel_key_t __key_t;
 typedef __key_t key_t;
 
-typedef uint32_t __ino_t;
+typedef __kernel_ino_t __ino_t;
 typedef __ino_t ino_t;
 
 typedef uint32_t __nlink_t;
@@ -72,9 +72,10 @@
 typedef void* __timer_t;
 typedef __timer_t timer_t;
 
-typedef int32_t __suseconds_t;
+typedef __kernel_suseconds_t __suseconds_t;
 typedef __suseconds_t suseconds_t;
 
+/* useconds_t is 32-bit on both LP32 and LP64. */
 typedef uint32_t __useconds_t;
 typedef __useconds_t useconds_t;
 
diff --git a/libc/include/utmp.h b/libc/include/utmp.h
index ffd3c92..d764227 100644
--- a/libc/include/utmp.h
+++ b/libc/include/utmp.h
@@ -36,9 +36,15 @@
 #define _PATH_WTMP      "/var/log/wtmp"
 #define _PATH_LASTLOG   "/var/log/lastlog"
 
-#define	UT_NAMESIZE	8
-#define	UT_LINESIZE	8
-#define	UT_HOSTSIZE	16
+#ifdef __LP64__
+#define UT_NAMESIZE 32
+#define UT_LINESIZE 32
+#define UT_HOSTSIZE 256
+#else
+#define UT_NAMESIZE 8
+#define UT_LINESIZE 8
+#define UT_HOSTSIZE 16
+#endif
 
 #define USER_PROCESS 7
 
diff --git a/libc/private/libc_logging.h b/libc/private/libc_logging.h
index 54e050a..822f232 100644
--- a/libc/private/libc_logging.h
+++ b/libc/private/libc_logging.h
@@ -68,14 +68,13 @@
   char msg[0];
 };
 
-__LIBC_HIDDEN__ void __libc_set_abort_message(const char* msg);
+void __android_set_abort_message(const char* msg);
 
 //
 // Formats a message to the log (priority 'fatal'), then aborts.
 //
 
 __LIBC_HIDDEN__ __noreturn void __libc_fatal(const char* format, ...) __printflike(1, 2);
-__noreturn void __android_fatal(const char* tag, const char* format, ...) __printflike(2, 3);
 
 //
 // Formats a message to the log (priority 'fatal'), but doesn't abort.
diff --git a/libc/stdio/fileext.h b/libc/stdio/fileext.h
index fa6fed6..1f2a3a3 100644
--- a/libc/stdio/fileext.h
+++ b/libc/stdio/fileext.h
@@ -29,6 +29,9 @@
  * $Citrus$
  */
 
+#ifndef _FILEEXT_H_
+#define _FILEEXT_H_
+
 #include <pthread.h>
 
 /*
@@ -59,3 +62,5 @@
 	(f)->_ext._base = (unsigned char *)(fext); \
 	_FILEEXT_INIT(f); \
 } while (0)
+
+#endif /* _FILEEXT_H_ */
diff --git a/libc/tzcode/strftime.c b/libc/tzcode/strftime.c
index 2a1db64..967629d 100644
--- a/libc/tzcode/strftime.c
+++ b/libc/tzcode/strftime.c
@@ -160,7 +160,7 @@
     tzset();
     warn = IN_NONE;
     p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn, locale);
-#if 0  /* ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */
+#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
     if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
         (void) fprintf(stderr, "\n");
         if (format == NULL)
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index b55f390..bacd1d7 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -17,7 +17,6 @@
 #ifndef _BIONIC_OPENBSD_COMPAT_H_included
 #define _BIONIC_OPENBSD_COMPAT_H_included
 
-#define _GNU_SOURCE
 #define __USE_BSD
 
 /* OpenBSD's <ctype.h> uses these names, which conflicted with stlport.
diff --git a/libc/upstream-openbsd/lib/libc/time/wcsftime.c b/libc/upstream-openbsd/lib/libc/time/wcsftime.c
index 5760493..21ccac7 100644
--- a/libc/upstream-openbsd/lib/libc/time/wcsftime.c
+++ b/libc/upstream-openbsd/lib/libc/time/wcsftime.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: wcsftime.c,v 1.2 2013/01/20 20:29:02 millert Exp $ */
+/*	$OpenBSD: wcsftime.c,v 1.3 2014/05/06 15:49:45 tedu Exp $ */
 #include "private.h"
 
 /*
@@ -110,10 +110,6 @@
 
 extern char *	tzname[];
 
-#ifndef YEAR_2000_NAME
-#define YEAR_2000_NAME	"CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
-#endif /* !defined YEAR_2000_NAME */
-
 #define IN_NONE	0
 #define IN_SOME	1
 #define IN_THIS	2
@@ -129,22 +125,6 @@
 	tzset();
 	warn = IN_NONE;
 	p = _fmt(((format == NULL) ? L"%c" : format), t, s, s + maxsize, &warn);
-#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
-	if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
-		(void) fprintf(stderr, "\n");
-		if (format == NULL)
-			(void) fprintf(stderr, "NULL strftime format ");
-		else	(void) fwprintf(stderr, "strftime format \"%ls\" ",
-				format);
-		(void) fprintf(stderr, "yields only two digits of years in ");
-		if (warn == IN_SOME)
-			(void) fprintf(stderr, "some locales");
-		else if (warn == IN_THIS)
-			(void) fprintf(stderr, "the current locale");
-		else	(void) fprintf(stderr, "all locales");
-		(void) fprintf(stderr, "\n");
-	}
-#endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */
 	if (p == s + maxsize) {
 		if (maxsize > 0)
 			s[maxsize - 1] = '\0';
diff --git a/libm/Android.mk b/libm/Android.mk
index 5f69d1e..d7d8bc1 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -234,6 +234,11 @@
     -DFLT_EVAL_METHOD=0 \
     -std=c99 \
     -include $(LOCAL_PATH)/freebsd-compat.h \
+    -Wno-missing-braces \
+    -Wno-parentheses \
+    -Wno-sign-compare \
+    -Wno-uninitialized \
+    -Wno-unknown-pragmas \
 
 libm_common_includes := $(LOCAL_PATH)/upstream-freebsd/lib/msun/src/
 
diff --git a/libm/include/math.h b/libm/include/math.h
index bd0241b..4d174f9 100644
--- a/libm/include/math.h
+++ b/libm/include/math.h
@@ -396,16 +396,23 @@
  * long double versions of ISO/POSIX math functions
  */
 #if __ISO_C_VISIBLE >= 1999
+long double	acoshl(long double);
 long double	acosl(long double);
+long double	asinhl(long double);
 long double	asinl(long double);
 long double	atan2l(long double, long double);
+long double	atanhl(long double);
 long double	atanl(long double);
 long double	cbrtl(long double);
 long double	ceill(long double);
 long double	copysignl(long double, long double) __pure2;
+long double	coshl(long double);
 long double	cosl(long double);
+long double	erfcl(long double);
+long double	erfl(long double);
 long double	exp2l(long double);
 long double	expl(long double);
+long double	expm1l(long double);
 long double	fabsl(long double) __pure2;
 long double	fdiml(long double, long double);
 long double	floorl(long double);
@@ -417,9 +424,14 @@
 long double	hypotl(long double, long double);
 int		ilogbl(long double) __pure2;
 long double	ldexpl(long double, int);
+long double	lgammal(long double);
 long long	llrintl(long double);
 long long	llroundl(long double);
+long double	log10l(long double);
+long double	log1pl(long double);
+long double	log2l(long double);
 long double	logbl(long double);
+long double	logl(long double);
 long		lrintl(long double);
 long		lroundl(long double);
 long double	modfl(long double, long double *); /* fundamentally !__pure2 */
@@ -429,53 +441,22 @@
 double		nexttoward(double, long double);
 float		nexttowardf(float, long double);
 long double	nexttowardl(long double, long double);
+long double	powl(long double, long double);
 long double	remainderl(long double, long double);
 long double	remquol(long double, long double, int *);
 long double	rintl(long double);
 long double	roundl(long double);
 long double	scalblnl(long double, long);
 long double	scalbnl(long double, int);
+long double	sinhl(long double);
 long double	sinl(long double);
 long double	sqrtl(long double);
+long double	tanhl(long double);
 long double	tanl(long double);
+long double	tgammal(long double);
 long double	truncl(long double);
 
 #endif /* __ISO_C_VISIBLE >= 1999 */
 __END_DECLS
 
 #endif /* !_MATH_H_ */
-
-/* separate header for cmath */
-#ifndef _MATH_EXTRA_H_
-#if __ISO_C_VISIBLE >= 1999
-#if _DECLARE_C99_LDBL_MATH
-
-#define _MATH_EXTRA_H_
-
-/*
- * extra long double versions of math functions for C99 and cmath
- */
-__BEGIN_DECLS
-
-long double	acoshl(long double);
-long double	asinhl(long double);
-long double	atanhl(long double);
-long double	coshl(long double);
-long double	erfcl(long double);
-long double	erfl(long double);
-long double	expm1l(long double);
-long double	lgammal(long double);
-long double	log10l(long double);
-long double	log1pl(long double);
-long double	log2l(long double);
-long double	logl(long double);
-long double	powl(long double, long double);
-long double	sinhl(long double);
-long double	tanhl(long double);
-long double	tgammal(long double);
-
-__END_DECLS
-
-#endif /* !_DECLARE_C99_LDBL_MATH */
-#endif /* __ISO_C_VISIBLE >= 1999 */
-#endif /* !_MATH_EXTRA_H_ */
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index 0b98e40..63ac719 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define _DECLARE_C99_LDBL_MATH 1
-
 // This include (and the associated definition of __test_capture_signbit)
 // must be placed before any files that include <cmath> (gtest.h in this case).
 //