Merge "Use __unused instead of UNUSED in linker.cpp"
diff --git a/libc/Android.mk b/libc/Android.mk
index 8cb85b7..3faa47f 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -771,6 +771,10 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_REQUIRED_MODULES := tzdata
 
+# Leave the symbols in the shared library so that stack unwinders can produce
+# meaningful name resolution.
+LOCAL_STRIP_MODULE := keep_symbols
+
 # WARNING: The only library libc.so should depend on is libdl.so!  If you add other libraries,
 # make sure to add -Wl,--exclude-libs=libgcc.a to the LOCAL_LDFLAGS for those libraries.  This
 # ensures that symbols that are pulled into those new libraries from libgcc.a are not declared
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 8d4b258..e597b2f 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -238,6 +238,7 @@
 int           connect(int, struct sockaddr*, socklen_t)   arm,arm64,mips,mips64,x86_64
 int           listen(int, int)                   arm,arm64,mips,mips64,x86_64
 int           accept(int, struct sockaddr*, socklen_t*)  arm,arm64,mips,mips64,x86_64
+int           accept4(int, struct sockaddr*, socklen_t*, int)  arm,arm64,mips,mips64,x86_64
 int           getsockname(int, struct sockaddr*, socklen_t*)  arm,arm64,mips,mips64,x86_64
 int           getpeername(int, struct sockaddr*, socklen_t*)  arm,arm64,mips,mips64,x86_64
 int           sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t)  arm,arm64,mips,mips64,x86_64
@@ -266,6 +267,7 @@
 int           getsockopt:socketcall:15(int, int, int, void*, socklen_t*)    x86
 int           sendmsg:socketcall:16(int, const struct msghdr*, unsigned int)  x86
 int           recvmsg:socketcall:17(int, struct msghdr*, unsigned int)   x86
+int           accept4:socketcall:18(int, struct sockaddr*, socklen_t*, int)  x86
 int           recvmmsg:socketcall:19(int, struct mmsghdr*, unsigned int, int, const struct timespec*)   x86
 int           sendmmsg:socketcall:20(int, struct mmsghdr*, unsigned int, int)   x86
 
diff --git a/libc/arch-arm/syscalls/accept4.S b/libc/arch-arm/syscalls/accept4.S
new file mode 100644
index 0000000..6d14e79
--- /dev/null
+++ b/libc/arch-arm/syscalls/accept4.S
@@ -0,0 +1,14 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(accept4)
+    mov     ip, r7
+    ldr     r7, =__NR_accept4
+    swi     #0
+    mov     r7, ip
+    cmn     r0, #(MAX_ERRNO + 1)
+    bxls    lr
+    neg     r0, r0
+    b       __set_errno
+END(accept4)
diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk
index 88da1f3..7b6b1c3 100644
--- a/libc/arch-arm64/arm64.mk
+++ b/libc/arch-arm64/arm64.mk
@@ -14,6 +14,11 @@
     upstream-freebsd/lib/libc/string/wcslen.c \
     upstream-freebsd/lib/libc/string/wcsrchr.c \
     upstream-freebsd/lib/libc/string/wmemcmp.c \
+    upstream-openbsd/lib/libc/locale/_def_numeric.c \
+    upstream-openbsd/lib/libc/locale/_def_messages.c \
+    upstream-openbsd/lib/libc/locale/_def_monetary.c \
+    upstream-openbsd/lib/libc/locale/_def_time.c \
+    upstream-openbsd/lib/libc/locale/localeconv.c \
     upstream-openbsd/lib/libc/string/bcopy.c \
     upstream-openbsd/lib/libc/string/strcat.c \
     upstream-openbsd/lib/libc/string/strcpy.c \
diff --git a/libc/arch-arm64/syscalls/accept4.S b/libc/arch-arm64/syscalls/accept4.S
new file mode 100644
index 0000000..3c9227f
--- /dev/null
+++ b/libc/arch-arm64/syscalls/accept4.S
@@ -0,0 +1,21 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(accept4)
+    stp     x29, x30, [sp, #-16]!
+    mov     x29,  sp
+    str     x8,       [sp, #-16]!
+
+    mov     x8, __NR_accept4
+    svc     #0
+
+    ldr     x8,       [sp], #16
+    ldp     x29, x30, [sp], #16
+
+    cmn     x0, #(MAX_ERRNO + 1)
+    cneg    x0, x0, hi
+    b.hi    __set_errno
+
+    ret
+END(accept4)
diff --git a/libc/arch-mips/syscalls/accept4.S b/libc/arch-mips/syscalls/accept4.S
new file mode 100644
index 0000000..ea1dc60
--- /dev/null
+++ b/libc/arch-mips/syscalls/accept4.S
@@ -0,0 +1,19 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(accept4)
+    .set noreorder
+    .cpload t9
+    li v0, __NR_accept4
+    syscall
+    bnez a3, 1f
+    move a0, v0
+    j ra
+    nop
+1:
+    la t9,__set_errno
+    j t9
+    nop
+    .set reorder
+END(accept4)
diff --git a/libc/arch-mips64/mips64.mk b/libc/arch-mips64/mips64.mk
index 28806e1..9b29f0d 100644
--- a/libc/arch-mips64/mips64.mk
+++ b/libc/arch-mips64/mips64.mk
@@ -16,6 +16,11 @@
     upstream-freebsd/lib/libc/string/wcslen.c \
     upstream-freebsd/lib/libc/string/wcsrchr.c \
     upstream-freebsd/lib/libc/string/wmemcmp.c \
+    upstream-openbsd/lib/libc/locale/_def_numeric.c \
+    upstream-openbsd/lib/libc/locale/_def_messages.c \
+    upstream-openbsd/lib/libc/locale/_def_monetary.c \
+    upstream-openbsd/lib/libc/locale/_def_time.c \
+    upstream-openbsd/lib/libc/locale/localeconv.c \
     upstream-openbsd/lib/libc/string/bcopy.c \
     upstream-openbsd/lib/libc/string/strcat.c \
     upstream-openbsd/lib/libc/string/strcmp.c \
diff --git a/libc/arch-mips64/syscalls/accept4.S b/libc/arch-mips64/syscalls/accept4.S
new file mode 100644
index 0000000..8b5cadb
--- /dev/null
+++ b/libc/arch-mips64/syscalls/accept4.S
@@ -0,0 +1,25 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(accept4)
+    .set push
+    .set noreorder
+    li v0, __NR_accept4
+    syscall
+    bnez a3, 1f
+    move a0, v0
+    j ra
+    nop
+1:
+    move t0, ra
+    bal     2f
+    nop
+2:
+    .cpsetup ra, t1, 2b
+    LA t9,__set_errno
+    .cpreturn
+    j t9
+    move ra, t0
+    .set pop
+END(accept4)
diff --git a/libc/arch-x86/syscalls/accept4.S b/libc/arch-x86/syscalls/accept4.S
new file mode 100644
index 0000000..dc3c1f5
--- /dev/null
+++ b/libc/arch-x86/syscalls/accept4.S
@@ -0,0 +1,27 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(accept4)
+    pushl   %ebx
+    pushl   %ecx
+    .cfi_def_cfa_offset 8
+    .cfi_rel_offset ebx, 0
+    .cfi_rel_offset ecx, 4
+    mov     $18, %ebx
+    mov     %esp, %ecx
+    addl    $12, %ecx
+    movl    $__NR_socketcall, %eax
+    int     $0x80
+    cmpl    $-MAX_ERRNO, %eax
+    jb      1f
+    negl    %eax
+    pushl   %eax
+    call    __set_errno
+    addl    $4, %esp
+    orl     $-1, %eax
+1:
+    popl    %ecx
+    popl    %ebx
+    ret
+END(accept4)
diff --git a/libc/arch-x86_64/syscalls/accept4.S b/libc/arch-x86_64/syscalls/accept4.S
new file mode 100644
index 0000000..d66d952
--- /dev/null
+++ b/libc/arch-x86_64/syscalls/accept4.S
@@ -0,0 +1,17 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(accept4)
+    movq    %rcx, %r10
+    movl    $__NR_accept4, %eax
+    syscall
+    cmpq    $-MAX_ERRNO, %rax
+    jb      1f
+    negl    %eax
+    movl    %eax, %edi
+    call    __set_errno
+    orq     $-1, %rax
+1:
+    ret
+END(accept4)
diff --git a/libc/arch-x86_64/x86_64.mk b/libc/arch-x86_64/x86_64.mk
index 9bce065..a3adaa4 100644
--- a/libc/arch-x86_64/x86_64.mk
+++ b/libc/arch-x86_64/x86_64.mk
@@ -18,6 +18,11 @@
     upstream-freebsd/lib/libc/string/wcslen.c \
     upstream-freebsd/lib/libc/string/wcsrchr.c \
     upstream-freebsd/lib/libc/string/wmemcmp.c \
+    upstream-openbsd/lib/libc/locale/_def_numeric.c \
+    upstream-openbsd/lib/libc/locale/_def_messages.c \
+    upstream-openbsd/lib/libc/locale/_def_monetary.c \
+    upstream-openbsd/lib/libc/locale/_def_time.c \
+    upstream-openbsd/lib/libc/locale/localeconv.c \
     upstream-openbsd/lib/libc/string/bcopy.c \
     upstream-openbsd/lib/libc/string/strcat.c \
     upstream-openbsd/lib/libc/string/strcmp.c \
diff --git a/libc/bionic/strtotimeval.c b/libc/bionic/strtotimeval.c
index 1c132ec..195381b 100644
--- a/libc/bionic/strtotimeval.c
+++ b/libc/bionic/strtotimeval.c
@@ -30,34 +30,29 @@
 #include <stdlib.h>
 #include <sys/time.h>
 
-char * strtotimeval (const char *str, struct timeval *ts)
-{
-    int n;
-    char *s, *s0;
-    long  fs;	/* Fractional seconds */
+char * strtotimeval(const char *str, struct timeval *ts) {
+  char *s;
+  long fs = 0; /* fractional seconds */
 
-    ts->tv_sec = strtoumax(str, &s, 10);
-    fs = 0;
+  ts->tv_sec = strtoumax(str, &s, 10);
 
-    if ( *s == '.' ) {
-	int  count;
+  if (*s == '.') {
+    s++;
+    int count = 0;
 
-        s0 = s+1;
-
-	/* read up to 6 digits */
-	fs    = 0;
-	count = 0;
-	while ( *s && isdigit(*s) )
-	{
-            if ( ++count < 7 )
-	        fs = fs*10 + (*s - '0');
-	    s++;
-	}
-
-	for ( ; count < 6; count++ )
-	    fs *= 10;
+    /* read up to 6 digits (microseconds) */
+    while (*s && isdigit(*s)) {
+      if (++count < 7) {
+        fs = fs*10 + (*s - '0');
+      }
+      s++;
     }
 
-    ts->tv_usec = fs;
-    return s;
+    for (; count < 6; count++) {
+      fs *= 10;
+    }
+  }
+
+  ts->tv_usec = fs;
+  return s;
 }
diff --git a/libc/include/locale.h b/libc/include/locale.h
index b6dbfdb..4efc564 100644
--- a/libc/include/locale.h
+++ b/libc/include/locale.h
@@ -51,12 +51,41 @@
 
 extern char* setlocale(int, const char*);
 
-#if !defined(__LP64__)
-// TODO: LP32 had these bogus declarations but LP64 should have a real struct lconv and localeconv(3).
+#if defined(__LP64__)
+struct lconv {
+    char* decimal_point;
+    char* thousands_sep;
+    char* grouping;
+    char* int_curr_symbol;
+    char* currency_symbol;
+    char* mon_decimal_point;
+    char* mon_thousands_sep;
+    char* mon_grouping;
+    char* positive_sign;
+    char* negative_sign;
+    char  int_frac_digits;
+    char  frac_digits;
+    char  p_cs_precedes;
+    char  p_sep_by_space;
+    char  n_cs_precedes;
+    char  n_sep_by_space;
+    char  p_sign_posn;
+    char  n_sign_posn;
+    /* ISO-C99 */
+    char  int_p_cs_precedes;
+    char  int_p_sep_by_space;
+    char  int_n_cs_precedes;
+    char  int_n_sep_by_space;
+    char  int_p_sign_posn;
+    char  int_n_sign_posn;
+};
+#else
+// Keep old declaration for ILP32 for compatibility
 struct lconv { };
-struct lconv* localeconv(void);
 #endif
 
+struct lconv* localeconv(void);
+
 __END_DECLS
 
 #endif /* _LOCALE_H_ */
diff --git a/libc/include/sys/localedef.h b/libc/include/sys/localedef.h
new file mode 100644
index 0000000..b6b5eb1
--- /dev/null
+++ b/libc/include/sys/localedef.h
@@ -0,0 +1,101 @@
+/*	$OpenBSD: localedef.h,v 1.3 1996/04/21 22:31:47 deraadt Exp $	*/
+/*	$NetBSD: localedef.h,v 1.4 1996/04/09 20:55:31 cgd Exp $	*/
+
+/*
+ * Copyright (c) 1994 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_LOCALEDEF_H_
+#define _SYS_LOCALEDEF_H_
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+typedef struct
+{
+	char *yesexpr;
+	char *noexpr;
+	char *yesstr;
+	char *nostr;
+} _MessagesLocale;
+
+extern const _MessagesLocale *_CurrentMessagesLocale;
+extern const _MessagesLocale  _DefaultMessagesLocale;
+
+
+typedef struct
+{
+	char *int_curr_symbol;
+	char *currency_symbol;
+	char *mon_decimal_point;
+	char *mon_thousands_sep;
+	char *mon_grouping;
+	char *positive_sign;
+	char *negative_sign;
+	char int_frac_digits;
+	char frac_digits;
+	char p_cs_precedes;
+	char p_sep_by_space;
+	char n_cs_precedes;
+	char n_sep_by_space;
+	char p_sign_posn;
+	char n_sign_posn;
+} _MonetaryLocale;
+
+extern const _MonetaryLocale *_CurrentMonetaryLocale;
+extern const _MonetaryLocale  _DefaultMonetaryLocale;
+
+
+typedef struct
+{
+	const char *decimal_point;
+	const char *thousands_sep;
+	const char *grouping;
+} _NumericLocale;
+
+extern const _NumericLocale *_CurrentNumericLocale;
+extern const _NumericLocale  _DefaultNumericLocale;
+
+
+typedef struct {
+	const char *abday[7];
+	const char *day[7];
+	const char *abmon[12];
+	const char *mon[12];
+	const char *am_pm[2];
+	const char *d_t_fmt;
+	const char *d_fmt;
+	const char *t_fmt;
+	const char *t_fmt_ampm;
+} _TimeLocale;
+
+extern const _TimeLocale *_CurrentTimeLocale;
+extern const _TimeLocale  _DefaultTimeLocale;
+
+#endif /* !_SYS_LOCALEDEF_H_ */
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index 62a5300..5001b2e 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -107,14 +107,14 @@
   int cmsg_type;
 };
 
-#define __CMSG_NXTHDR(ctl, len, cmsg) __cmsg_nxthdr((ctl),(len),(cmsg))
-#define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg))
+#define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr((mhdr)->msg_control, (mhdr)->msg_controllen, (cmsg))
 #define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )
 #define CMSG_DATA(cmsg) ((void*)((char*)(cmsg) + CMSG_ALIGN(sizeof(struct cmsghdr))))
 #define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len))
 #define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
-#define __CMSG_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr) ?   (struct cmsghdr*)(ctl) :   (struct cmsghdr*)NULL)
-#define CMSG_FIRSTHDR(msg) __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+#define CMSG_FIRSTHDR(msg) \
+  ((msg)->msg_controllen >= sizeof(struct cmsghdr) \
+   ? (struct cmsghdr*) (msg)->msg_control : (struct cmsghdr*) NULL)
 #define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) &&   (cmsg)->cmsg_len <= (unsigned long)   ((mhdr)->msg_controllen -   ((char*)(cmsg) - (char*)(mhdr)->msg_control)))
 
 #ifdef __GNUC__
@@ -134,10 +134,6 @@
   return __ptr;
 }
 
-__KINLINE struct cmsghdr* cmsg_nxthdr (struct msghdr* __msg, struct cmsghdr* __cmsg) {
-  return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg);
-}
-
 #define SCM_RIGHTS 0x01
 #define SCM_CREDENTIALS 0x02
 #define SCM_SECURITY 0x03
@@ -302,6 +298,7 @@
 __socketcall int shutdown(int, int);
 __socketcall int socket(int, int, int);
 __socketcall int socketpair(int, int, int, int*);
+__socketcall int accept4(int, struct sockaddr*, socklen_t*, int);
 
 extern ssize_t send(int, const void*, size_t, int);
 extern ssize_t recv(int, void*, size_t, int);
diff --git a/libc/include/sys/socketcalls.h b/libc/include/sys/socketcalls.h
index c74f463..09c079f 100644
--- a/libc/include/sys/socketcalls.h
+++ b/libc/include/sys/socketcalls.h
@@ -47,5 +47,6 @@
 #define SYS_GETSOCKOPT  15              /* sys_getsockopt(2)            */
 #define SYS_SENDMSG     16              /* sys_sendmsg(2)               */
 #define SYS_RECVMSG     17              /* sys_recvmsg(2)               */
+#define SYS_ACCEPT4     18              /* sys_accept4(2)               */
 
 #endif /* _SYS_SOCKETCALLS_H_ */
diff --git a/libc/stdlib/strtod.c b/libc/stdlib/strtod.c
index 0a19446..b39c90e 100644
--- a/libc/stdlib/strtod.c
+++ b/libc/stdlib/strtod.c
@@ -1332,13 +1332,14 @@
 	Bigint *bb1, *bd0;
 	Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */
 
-	CONST char decimal_point = '.';
-#if 0 /* BEGIN android-changed: no localeconv. */
+#if defined(__LP64__) /* BEGIN android-changed: no localeconv for ILP32. */
 #ifndef KR_headers
 	CONST char decimal_point = localeconv()->decimal_point[0];
 #else
 	CONST char decimal_point = '.';
 #endif
+#else
+	CONST char decimal_point = '.';
 #endif /* END android-changed */
 
 	sign = nz0 = nz = 0;
diff --git a/libc/upstream-openbsd/lib/libc/locale/_def_messages.c b/libc/upstream-openbsd/lib/libc/locale/_def_messages.c
new file mode 100644
index 0000000..1ed653a
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/locale/_def_messages.c
@@ -0,0 +1,18 @@
+/*	$OpenBSD: _def_messages.c,v 1.5 2005/08/08 08:05:35 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+const _MessagesLocale _DefaultMessagesLocale =
+{
+	"^[Yy]",
+	"^[Nn]",
+	"yes",
+	"no"
+} ;
+
+const _MessagesLocale *_CurrentMessagesLocale = &_DefaultMessagesLocale;
diff --git a/libc/upstream-openbsd/lib/libc/locale/_def_monetary.c b/libc/upstream-openbsd/lib/libc/locale/_def_monetary.c
new file mode 100644
index 0000000..aa92c75
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/locale/_def_monetary.c
@@ -0,0 +1,30 @@
+/*	$OpenBSD: _def_monetary.c,v 1.4 2005/08/08 08:05:35 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <limits.h>
+#include <locale.h>
+
+const _MonetaryLocale _DefaultMonetaryLocale =
+{
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	CHAR_MAX,
+	CHAR_MAX,
+	CHAR_MAX,
+	CHAR_MAX,
+	CHAR_MAX,
+	CHAR_MAX,
+	CHAR_MAX,
+	CHAR_MAX
+};
+
+const _MonetaryLocale *_CurrentMonetaryLocale = &_DefaultMonetaryLocale;
diff --git a/libc/upstream-openbsd/lib/libc/locale/_def_numeric.c b/libc/upstream-openbsd/lib/libc/locale/_def_numeric.c
new file mode 100644
index 0000000..6511254
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/locale/_def_numeric.c
@@ -0,0 +1,17 @@
+/*	$OpenBSD: _def_numeric.c,v 1.4 2005/08/08 08:05:35 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+const _NumericLocale _DefaultNumericLocale =
+{
+	".",
+	"",
+	""
+};
+
+const _NumericLocale *_CurrentNumericLocale = &_DefaultNumericLocale;
diff --git a/libc/upstream-openbsd/lib/libc/locale/_def_time.c b/libc/upstream-openbsd/lib/libc/locale/_def_time.c
new file mode 100644
index 0000000..75179a6
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/locale/_def_time.c
@@ -0,0 +1,36 @@
+/*	$OpenBSD: _def_time.c,v 1.5 2011/10/09 06:39:53 ajacoutot Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+const _TimeLocale _DefaultTimeLocale =
+{
+	{
+		"Sun","Mon","Tue","Wed","Thu","Fri","Sat",
+	},
+	{
+		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
+		"Friday", "Saturday"
+	},
+	{
+		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+	},
+	{
+		"January", "February", "March", "April", "May", "June", "July",
+		"August", "September", "October", "November", "December"
+	},
+	{
+		"AM", "PM"
+	},
+	"%a %b %e %H:%M:%S %Y",
+	"%m/%d/%y",
+	"%H:%M:%S",
+	"%I:%M:%S %p"
+};
+
+const _TimeLocale *_CurrentTimeLocale = &_DefaultTimeLocale;
diff --git a/libc/upstream-openbsd/lib/libc/locale/localeconv.c b/libc/upstream-openbsd/lib/libc/locale/localeconv.c
new file mode 100644
index 0000000..989eb4b
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/locale/localeconv.c
@@ -0,0 +1,59 @@
+/*	$OpenBSD: localeconv.c,v 1.5 2005/08/08 08:05:35 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+/*
+ * The localeconv() function constructs a struct lconv from the current
+ * monetary and numeric locales.
+ *
+ * Because localeconv() may be called many times (especially by library
+ * routines like printf() & strtod()), the approprate members of the
+ * lconv structure are computed only when the monetary or numeric
+ * locale has been changed.
+ */
+int __mlocale_changed = 1;
+int __nlocale_changed = 1;
+
+/*
+ * Return the current locale conversion.
+ */
+struct lconv *
+localeconv(void)
+{
+    static struct lconv ret;
+
+    if (__mlocale_changed) {
+	/* LC_MONETARY */
+	ret.int_curr_symbol	= _CurrentMonetaryLocale->int_curr_symbol;
+	ret.currency_symbol	= _CurrentMonetaryLocale->currency_symbol;
+	ret.mon_decimal_point	= _CurrentMonetaryLocale->mon_decimal_point;
+	ret.mon_thousands_sep	= _CurrentMonetaryLocale->mon_thousands_sep;
+	ret.mon_grouping	= _CurrentMonetaryLocale->mon_grouping;
+	ret.positive_sign	= _CurrentMonetaryLocale->positive_sign;
+	ret.negative_sign	= _CurrentMonetaryLocale->negative_sign;
+	ret.int_frac_digits	= _CurrentMonetaryLocale->int_frac_digits;
+	ret.frac_digits		= _CurrentMonetaryLocale->frac_digits;
+	ret.p_cs_precedes	= _CurrentMonetaryLocale->p_cs_precedes;
+	ret.p_sep_by_space	= _CurrentMonetaryLocale->p_sep_by_space;
+	ret.n_cs_precedes	= _CurrentMonetaryLocale->n_cs_precedes;
+	ret.n_sep_by_space	= _CurrentMonetaryLocale->n_sep_by_space;
+	ret.p_sign_posn		= _CurrentMonetaryLocale->p_sign_posn;
+	ret.n_sign_posn		= _CurrentMonetaryLocale->n_sign_posn;
+	__mlocale_changed = 0;
+    }
+
+    if (__nlocale_changed) {
+	/* LC_NUMERIC */
+	ret.decimal_point	= (char *) _CurrentNumericLocale->decimal_point;
+	ret.thousands_sep	= (char *) _CurrentNumericLocale->thousands_sep;
+	ret.grouping		= (char *) _CurrentNumericLocale->grouping;
+	__nlocale_changed = 0;
+    }
+
+    return (&ret);
+}
diff --git a/linker/Android.mk b/linker/Android.mk
index 1d03a9c..c517a30 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -1,9 +1,70 @@
 LOCAL_PATH:= $(call my-dir)
 
-linker_2nd_arch_var_prefix :=
-include $(LOCAL_PATH)/linker.mk
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
 
+LOCAL_SRC_FILES:= \
+    debugger.cpp \
+    dlfcn.cpp \
+    linker.cpp \
+    linker_environ.cpp \
+    linker_phdr.cpp \
+    rt.cpp \
+
+LOCAL_SRC_FILES_arm     := arch/arm/begin.S
+LOCAL_SRC_FILES_arm64   := arch/arm64/begin.S
+LOCAL_SRC_FILES_x86     := arch/x86/begin.c
+LOCAL_SRC_FILES_x86_64  := arch/x86_64/begin.S
+LOCAL_SRC_FILES_mips    := arch/mips/begin.S
+
+LOCAL_LDFLAGS := \
+    -shared \
+    -Wl,-Bsymbolic \
+    -Wl,--exclude-libs,ALL \
+
+LOCAL_CFLAGS += \
+    -fno-stack-protector \
+    -Wstrict-overflow=5 \
+    -fvisibility=hidden \
+    -Wall -Wextra -Werror \
+
+LOCAL_CONLYFLAGS += \
+    -std=gnu99 \
+
+LOCAL_CPPFLAGS += \
+    -std=gnu++11 \
+
+# We need to access Bionic private headers in the linker.
+LOCAL_CFLAGS += -I$(LOCAL_PATH)/../libc/
+
+# we don't want crtbegin.o (because we have begin.o), so unset it
+# just for this module
+LOCAL_NO_CRT := true
+# TODO: split out the asflags.
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/linker_executable.mk
+
+LOCAL_STATIC_LIBRARIES := libc_nomalloc
+
+LOCAL_FORCE_STATIC_EXECUTABLE := true # not necessary when not including BUILD_EXECUTABLE
+
+LOCAL_2ND_ARCH_VAR_PREFIX := $(linker_2nd_arch_var_prefix)
+
+LOCAL_MODULE := linker
+LOCAL_MODULE_STEM_32 := linker
+LOCAL_MODULE_STEM_64 := linker64
+LOCAL_MULTILIB := both
+
+include $(LOCAL_PATH)/linker_executable.mk
 ifdef TARGET_2ND_ARCH
-linker_2nd_arch_var_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
-include $(LOCAL_PATH)/linker.mk
+LOCAL_2ND_ARCH_VAR_PREFIX := $(TARGET_2ND_ARCH_VAR_PREFIX)
+OVERRIDE_BUILT_MODULE_PATH :=
+LOCAL_BUILT_MODULE :=
+LOCAL_INSTALLED_MODULE :=
+LOCAL_MODULE_STEM :=
+LOCAL_BUILT_MODULE_STEM :=
+LOCAL_INSTALLED_MODULE_STEM :=
+LOCAL_INTERMEDIATE_TARGETS :=
+include $(LOCAL_PATH)/linker_executable.mk
 endif
diff --git a/linker/linker.mk b/linker/linker.mk
deleted file mode 100644
index 384435a..0000000
--- a/linker/linker.mk
+++ /dev/null
@@ -1,58 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    debugger.cpp \
-    dlfcn.cpp \
-    linker.cpp \
-    linker_environ.cpp \
-    linker_phdr.cpp \
-    rt.cpp \
-
-LOCAL_SRC_FILES_arm     := arch/arm/begin.S
-LOCAL_SRC_FILES_arm64   := arch/arm64/begin.S
-LOCAL_SRC_FILES_x86     := arch/x86/begin.c
-LOCAL_SRC_FILES_x86_64  := arch/x86_64/begin.S
-LOCAL_SRC_FILES_mips    := arch/mips/begin.S
-
-LOCAL_LDFLAGS := \
-    -shared \
-    -Wl,-Bsymbolic \
-    -Wl,--exclude-libs,ALL \
-
-LOCAL_CFLAGS += \
-    -fno-stack-protector \
-    -Wstrict-overflow=5 \
-    -fvisibility=hidden \
-    -Wall -Wextra -Werror \
-
-LOCAL_CONLYFLAGS += \
-    -std=gnu99 \
-
-LOCAL_CPPFLAGS += \
-    -std=gnu++11 \
-
-# We need to access Bionic private headers in the linker.
-LOCAL_CFLAGS += -I$(LOCAL_PATH)/../libc/
-
-# we don't want crtbegin.o (because we have begin.o), so unset it
-# just for this module
-LOCAL_NO_CRT := true
-# TODO: split out the asflags.
-LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/linker.mk $(LOCAL_PATH)/linker_executable.mk
-
-LOCAL_STATIC_LIBRARIES := libc_nomalloc
-
-LOCAL_FORCE_STATIC_EXECUTABLE := true # not necessary when not including BUILD_EXECUTABLE
-
-LOCAL_2ND_ARCH_VAR_PREFIX := $(linker_2nd_arch_var_prefix)
-
-ifeq ($(TARGET_IS_64_BIT)|$(linker_2nd_arch_var_prefix),true|)
-LOCAL_MODULE := linker64
-else
-LOCAL_MODULE := linker
-endif
-
-include $(LOCAL_PATH)/linker_executable.mk
diff --git a/tests/Android.mk b/tests/Android.mk
index 8dffa2f..788dbcf 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -50,6 +50,7 @@
     inttypes_test.cpp \
     libc_logging_test.cpp \
     libgen_test.cpp \
+    locale_test.cpp \
     malloc_test.cpp \
     math_test.cpp \
     netdb_test.cpp \
@@ -81,6 +82,7 @@
     system_properties_test.cpp \
     time_test.cpp \
     unistd_test.cpp \
+    accept4_test.cpp \
 
 libBionicStandardTests_cflags := \
     $(test_cflags) \
diff --git a/tests/accept4_test.cpp b/tests/accept4_test.cpp
new file mode 100644
index 0000000..2e6c808
--- /dev/null
+++ b/tests/accept4_test.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+/*
+ * Contributed by: Intel Corporation, 2014
+ */
+
+#include <gtest/gtest.h>
+
+#if defined(__BIONIC__)
+  #define SOCK_CLOEXEC_SUPPORTED 1
+#elif defined(__GLIBC_PREREQ)
+  #if __GLIBC_PREREQ(2, 9)
+    #define SOCK_CLOEXEC_SUPPORTED 1
+  #endif
+#endif
+
+#if defined(SOCK_CLOEXEC_SUPPORTED)
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <fcntl.h>
+
+#define SOCK_PATH "test"
+
+static void* ConnectFn(void*) {
+  int fd = socket(PF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+  if (fd < 0) {
+    GTEST_LOG_(ERROR) << "socket call failed: " << strerror(errno);
+    return reinterpret_cast<void*>(-1);
+  }
+
+  struct sockaddr_un addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.sun_family = AF_UNIX;
+  addr.sun_path[0] = '\0';
+  strcpy(addr.sun_path + 1, SOCK_PATH);
+
+  if (connect(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) < 0) {
+    GTEST_LOG_(ERROR) << "connect call failed: " << strerror(errno);
+    close(fd);
+    return reinterpret_cast<void*>(-1);
+  }
+
+  close(fd);
+
+  return NULL;
+}
+#endif
+
+TEST(accept4, smoke) {
+#if defined(SOCK_CLOEXEC_SUPPORTED)
+  int fd = socket(PF_UNIX, SOCK_SEQPACKET, 0);
+  ASSERT_NE(fd, -1) << strerror(errno);
+
+  struct sockaddr_un addr;
+  memset(&addr, 0, sizeof(addr));
+  addr.sun_family = AF_UNIX;
+  addr.sun_path[0] = '\0';
+  strcpy(addr.sun_path + 1, SOCK_PATH);
+
+  ASSERT_NE(-1, bind(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr))) << strerror(errno);
+
+  ASSERT_NE(-1, listen(fd, 1)) << strerror(errno);
+
+  pthread_t thread;
+  ASSERT_EQ(0, pthread_create(&thread, NULL, ConnectFn, NULL));
+
+  fd_set read_set;
+  FD_ZERO(&read_set);
+  FD_SET(fd, &read_set);
+  timeval tv;
+  tv.tv_sec = 5;
+  tv.tv_usec = 0;
+  ASSERT_LT(0, select(fd+1, &read_set, NULL, NULL, &tv));
+
+  socklen_t len = sizeof(addr);
+  int fd_acc = accept4(fd, reinterpret_cast<struct sockaddr*>(&addr), &len, SOCK_CLOEXEC);
+  ASSERT_NE(fd_acc, -1) << strerror(errno);
+
+  // Check that the flag was set properly.
+  ASSERT_EQ(FD_CLOEXEC, fcntl(fd_acc, F_GETFD) & FD_CLOEXEC);
+
+  void* ret_val;
+  pthread_join(thread, &ret_val);
+  ASSERT_EQ(NULL, ret_val);
+
+  close(fd_acc);
+  close(fd);
+#else
+  GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+}
diff --git a/tests/locale_test.cpp b/tests/locale_test.cpp
new file mode 100644
index 0000000..df58a70
--- /dev/null
+++ b/tests/locale_test.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <locale.h>
+
+TEST(locale, localeconv) {
+#ifdef __LP64__
+  ASSERT_STREQ(".", localeconv()->decimal_point);
+  ASSERT_STREQ("", localeconv()->currency_symbol);
+#else
+  GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 26b7775..c055769 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -387,3 +387,51 @@
   ASSERT_EQ(ESRCH, pthread_detach(tdd.thread_id));
 #endif
 }
+
+TEST(time, strtotimeval) {
+#if defined(__BIONIC__)
+  struct timeval tv1;
+  char* rest1 = strtotimeval("10.123456", &tv1);
+  ASSERT_EQ(10, tv1.tv_sec);
+  ASSERT_EQ(123456, tv1.tv_usec);
+  ASSERT_EQ('\0', *rest1);
+
+  // strtotimeval interprets the fractional part as microseconds and thus will
+  // only consider its first 6 digits. Even so it should consume all valid
+  // digits.
+  struct timeval tv2;
+  char* rest2 = strtotimeval(".1234567", &tv2);
+  ASSERT_EQ(0, tv2.tv_sec);
+  ASSERT_EQ(123456, tv2.tv_usec);
+  ASSERT_EQ('\0', *rest2);
+
+  struct timeval tv3;
+  char* rest3 = strtotimeval("1.1a", &tv3);
+  ASSERT_EQ(1, tv3.tv_sec);
+  ASSERT_EQ(100000, tv3.tv_usec);
+  ASSERT_EQ('a', *rest3);
+
+  struct timeval tv4;
+  char* rest4 = strtotimeval("a", &tv4);
+  ASSERT_EQ(0, tv4.tv_sec);
+  ASSERT_EQ(0, tv4.tv_usec);
+  ASSERT_EQ('a', *rest4);
+
+  struct timeval tv5;
+  char* rest5 = strtotimeval("0", &tv5);
+  ASSERT_EQ(0, tv5.tv_sec);
+  ASSERT_EQ(0, tv5.tv_usec);
+  ASSERT_EQ('\0', *rest5);
+
+  // TODO: should we reject this case and just return '.'?
+  struct timeval tv6;
+  char* rest6 = strtotimeval(".", &tv6);
+  ASSERT_EQ(0, tv6.tv_sec);
+  ASSERT_EQ(0, tv6.tv_usec);
+  ASSERT_EQ('\0', *rest6);
+
+#else // __BIONIC__
+  GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif // __BIONIC__
+}
+