merge in jb-mr2-release history after reset to master
diff --git a/libc/Android.mk b/libc/Android.mk
index d5ef82e..8ae1419 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -270,6 +270,7 @@
     bionic/brk.cpp \
     bionic/debug_format.cpp \
     bionic/dirent.cpp \
+    bionic/__errno.c \
     bionic/eventfd.cpp \
     bionic/__fgets_chk.cpp \
     bionic/getauxval.cpp \
@@ -299,6 +300,7 @@
     bionic/__strncpy_chk.cpp \
     bionic/strsignal.cpp \
     bionic/stubs.cpp \
+    bionic/sysconf.cpp \
     bionic/tdestroy.cpp \
     bionic/tmpfile.cpp \
     bionic/__umask_chk.cpp \
@@ -349,23 +351,6 @@
     upstream-netbsd/libc/string/strxfrm.c \
     upstream-netbsd/libc/unistd/killpg.c \
 
-# The following files are common, but must be compiled
-# with different C flags when building a static C library.
-#
-# The reason for this is the implementation of __get_tls()
-# that will differ between the shared and static versions
-# of the library.
-#
-# See comments in private/bionic_tls.h for more details.
-#
-# NOTE: bionic/pthread.c is added later to this list
-#       because it needs special handling on ARM, see
-#       below.
-#
-libc_static_common_src_files := \
-        bionic/__errno.c \
-        bionic/sysconf.cpp \
-
 # Architecture specific source files go here
 # =========================================================
 ifeq ($(TARGET_ARCH),arm)
@@ -423,31 +408,32 @@
 
 ifeq ($(TARGET_ARCH),x86)
 libc_common_src_files += \
-	arch-x86/bionic/__get_sp.S \
-	arch-x86/bionic/__get_tls.c \
-	arch-x86/bionic/__set_tls.c \
-	arch-x86/bionic/clone.S \
-	arch-x86/bionic/_exit_with_stack_teardown.S \
-	arch-x86/bionic/futex_x86.S \
-	arch-x86/bionic/setjmp.S \
-	arch-x86/bionic/_setjmp.S \
-	arch-x86/bionic/sigsetjmp.S \
-	arch-x86/bionic/vfork.S \
-	arch-x86/bionic/syscall.S \
-	arch-x86/string/bcopy_wrapper.S \
-	arch-x86/string/memcpy_wrapper.S \
-	arch-x86/string/memmove_wrapper.S \
-	arch-x86/string/bzero_wrapper.S \
-	arch-x86/string/memcmp_wrapper.S \
-	arch-x86/string/memset_wrapper.S \
-	arch-x86/string/strcmp_wrapper.S \
-	arch-x86/string/strncmp_wrapper.S \
-	arch-x86/string/strlen_wrapper.S \
-	string/strcpy.c \
-	bionic/pthread-atfork.c \
-	bionic/pthread-rwlocks.c \
-	bionic/pthread-timers.c \
-	bionic/ptrace.c
+    arch-x86/bionic/clone.S \
+    arch-x86/bionic/_exit_with_stack_teardown.S \
+    arch-x86/bionic/futex_x86.S \
+    arch-x86/bionic/__get_sp.S \
+    arch-x86/bionic/__get_tls.c \
+    arch-x86/bionic/_setjmp.S \
+    arch-x86/bionic/setjmp.S \
+    arch-x86/bionic/__set_tls.c \
+    arch-x86/bionic/sigsetjmp.S \
+    arch-x86/bionic/syscall.S \
+    arch-x86/bionic/vfork.S \
+    arch-x86/string/bcopy_wrapper.S \
+    arch-x86/string/bzero_wrapper.S \
+    arch-x86/string/ffs.S \
+    arch-x86/string/memcmp_wrapper.S \
+    arch-x86/string/memcpy_wrapper.S \
+    arch-x86/string/memmove_wrapper.S \
+    arch-x86/string/memset_wrapper.S \
+    arch-x86/string/strcmp_wrapper.S \
+    arch-x86/string/strlen_wrapper.S \
+    arch-x86/string/strncmp_wrapper.S \
+    bionic/pthread-atfork.c \
+    bionic/pthread-rwlocks.c \
+    bionic/pthread-timers.c \
+    bionic/ptrace.c \
+    string/strcpy.c \
 
 libc_static_common_src_files += \
     bionic/pthread.c \
@@ -545,18 +531,8 @@
   libc_common_cflags += -fstrict-aliasing
   libc_crt_target_cflags := -mthumb-interwork
   #
-  # Define HAVE_ARM_TLS_REGISTER macro to indicate to the C library
-  # that it should access the hardware TLS register directly in
-  # private/bionic_tls.h
-  #
-  # The value must match your kernel configuration
-  #
-  ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
-    libc_common_cflags += -DHAVE_ARM_TLS_REGISTER
-  endif
-  #
-  # Define HAVE_32_BYTE_CACHE_LINES to indicate to C
-  # library it should use to 32-byte version of memcpy, and not
+  # Define HAVE_32_BYTE_CACHE_LINES to indicate to the C library
+  # that it should use the 32-byte version of memcpy, not
   # the 64-byte version.
   #
   ifeq ($(ARCH_ARM_HAVE_32_BYTE_CACHE_LINES),true)
@@ -825,10 +801,10 @@
 # ========================================================
 #
 # This is a version of the static C library that does not
-# include malloc. It's useful in situations when calling
-# the user wants to provide their own malloc implementation,
-# or wants to explicitly disallow the use of the use of malloc,
-# like the dynamic loader.
+# include malloc. It's useful in situations when the user wants
+# to provide their own malloc implementation, or wants to
+# explicitly disallow the use of the use of malloc,
+# such as in the dynamic loader.
 
 include $(CLEAR_VARS)
 
diff --git a/libc/arch-arm/bionic/ffs.S b/libc/arch-arm/bionic/ffs.S
index c59091f..701af8c 100644
--- a/libc/arch-arm/bionic/ffs.S
+++ b/libc/arch-arm/bionic/ffs.S
@@ -31,55 +31,11 @@
 #include <machine/asm.h>
 #include <machine/cpu-features.h>
 
-/*
- * ffs - find first set bit, this algorithm isolates the first set
- * bit, then multiplies the number by 0x0450fbaf which leaves the top
- * 6 bits as an index into the table.  This algorithm should be a win
- * over the checking each bit in turn as per the C compiled version.
- *
- * Some newer ARM architectures have an instruction named
- * CLZ (count leading Zero's) that is used
- *
- * This is the ffs algorithm devised by d.seal and posted to comp.sys.arm on
- * 16 Feb 1994.
- */
-
 ENTRY(ffs)
 	/* Standard trick to isolate bottom bit in r0 or 0 if r0 = 0 on entry */
  	rsb     r1, r0, #0
  	ands    r0, r0, r1
-#ifndef __ARM_HAVE_CLZ
-	/*
-	 * now r0 has at most one set bit, call this X
-	 * if X = 0, all further instructions are skipped
-	 */
-	adrne   r2, .L_ffs_table
-	orrne   r0, r0, r0, lsl #4  /* r0 = X * 0x11 */ 
-	orrne   r0, r0, r0, lsl #6  /* r0 = X * 0x451 */
-	rsbne   r0, r0, r0, lsl #16 /* r0 = X * 0x0450fbaf */
-              
-	/* now lookup in table indexed on top 6 bits of r0 */
-	ldrneb  r0, [ r2, r0, lsr #26 ]
-
-	bx		lr
-END(ffs)
-
-.text;
-.type .L_ffs_table, _ASM_TYPE_OBJECT;
-.L_ffs_table:
-/*               0   1   2   3   4   5   6   7           */
-	.byte	 0,  1,  2, 13,  3,  7,  0, 14  /*  0- 7 */
-	.byte	 4,  0,  8,  0,  0,  0,  0, 15  /*  8-15 */
-	.byte	11,  5,  0,  0,  9,  0,  0, 26  /* 16-23 */
-	.byte	 0,  0,  0,  0,  0, 22, 28, 16  /* 24-31 */
-	.byte	32, 12,  6,  0,  0,  0,  0,  0	/* 32-39 */
-	.byte	10,  0,  0, 25,  0,  0, 21, 27  /* 40-47 */
-	.byte	31,  0,  0,  0,  0, 24,  0, 20  /* 48-55 */
-	.byte   30,  0, 23, 19, 29, 18, 17,  0  /* 56-63 */
-#else /* !defined(__ARM_HAVE_CLZ) */
 	clzne	r0, r0
 	rsbne	r0, r0, #32
 	bx		lr
 END(ffs)
-#endif /* !defined(__ARM_HAVE_CLZ) */
-
diff --git a/libc/arch-arm/bionic/memcmp.S b/libc/arch-arm/bionic/memcmp.S
index d6d3ca1..7fb4283 100644
--- a/libc/arch-arm/bionic/memcmp.S
+++ b/libc/arch-arm/bionic/memcmp.S
@@ -115,7 +115,7 @@
          * pointer somewhere else
          */
          mov        r4, r0
-        
+
         /* align first pointer to word boundary
          * offset = -src & 3
          */
@@ -151,7 +151,7 @@
         ldr         ip, [r1]
         subs        r2, r2, #(32 + 4)
         bmi         1f
-        
+
 0:      pld         [r4, #(CACHE_LINE_SIZE * 2)]
         pld         [r1, #(CACHE_LINE_SIZE * 2)]
         ldr         r0, [r4], #4
@@ -178,14 +178,14 @@
         ldreq       r0, [r4], #4
         ldreq       ip, [r1, #4]!
         eoreqs      r0, r0, lr
-        bne         2f        
+        bne         2f
         subs        r2, r2, #32
         bhs         0b
 
         /* do we have at least 4 bytes left? */
 1:      adds        r2, r2, #(32 - 4 + 4)
         bmi         4f
-        
+
         /* finish off 4 bytes at a time */
 3:      ldr         r0, [r4], #4
         ldr         ip, [r1], #4
@@ -233,17 +233,14 @@
         subs        r2, r2, #1
         bne         11b
         bx          lr
-END(memcmp)
-
-
 
 5:      /*************** non-congruent case ***************/
-        and         r0, r1, #3      
+        and         r0, r1, #3
         cmp         r0, #2
         bne         4f
 
         /* here, offset is 2 (16-bits aligned, special cased) */
-        
+
         /* make sure we have at least 16 bytes to process */
         subs        r2, r2, #16
         addmi       r2, r2, #16
@@ -341,3 +338,4 @@
         mov         r2, #4
 		ldmfd		sp!, {r5, r6, r7}
         b           8b
+END(memcmp)
diff --git a/libc/arch-arm/bionic/memset.S b/libc/arch-arm/bionic/memset.S
index 54f74de..102d541 100644
--- a/libc/arch-arm/bionic/memset.S
+++ b/libc/arch-arm/bionic/memset.S
@@ -42,6 +42,7 @@
 ENTRY(bzero)
         mov     r2, r1
         mov     r1, #0
+        // Fall through to memset...
 END(bzero)
 
 ENTRY(memset)
diff --git a/libc/arch-x86/bionic/_setjmp.S b/libc/arch-x86/bionic/_setjmp.S
index ac62635..9221138 100644
--- a/libc/arch-x86/bionic/_setjmp.S
+++ b/libc/arch-x86/bionic/_setjmp.S
@@ -54,6 +54,7 @@
 	movl	%edi,20(%eax)
 	xorl	%eax,%eax
 	ret
+END(_setjmp)
 
 ENTRY(_longjmp)
 	movl	4(%esp),%edx
@@ -69,3 +70,4 @@
 	incl	%eax
 1:	movl	%ecx,0(%esp)
 	ret
+END(_longjmp)
diff --git a/libc/arch-x86/bionic/clone.S b/libc/arch-x86/bionic/clone.S
index 6f84724..e7bc3ee 100644
--- a/libc/arch-x86/bionic/clone.S
+++ b/libc/arch-x86/bionic/clone.S
@@ -21,27 +21,33 @@
 
         subl    $16, %ecx
         movl    20(%esp), %ebx
+
+        # make system call
         movl    $__NR_clone, %eax
         int     $0x80
-        test    %eax, %eax
-        jns     1f
+
+        cmpl    $0, %eax
+        je      pc_child
+        jg      pc_parent
 
         # an error occurred, set errno and return -1
         negl    %eax
+        pushl   %eax
         call    __set_errno
+        addl    $4, %esp
         orl     $-1, %eax
-        jmp     2f
+        jmp     pc_return
 
-1:
-        jnz     2f
-
+pc_child:
         # we're in the child thread now, call __thread_entry
         # with the appropriate arguments on the child stack
         # we already placed most of them
         call    __thread_entry
         hlt
 
-2:
+pc_parent:
+        # we're the parent; nothing to do.
+pc_return:
         popl    %ecx
         popl    %ebx
         ret
@@ -75,27 +81,33 @@
         movl    24(%esp), %edx
         movl    32(%esp), %esi
         movl    28(%esp), %edi
+
+        # make system call
         movl    $__NR_clone, %eax
         int     $0x80
-        test    %eax, %eax
-        jns     1f
+
+        cmpl    $0, %eax
+        je      bc_child
+        jg      bc_parent
 
         # an error occurred, set errno and return -1
         negl    %eax
+        pushl   %eax
         call    __set_errno
+        addl    $4, %esp
         orl     $-1, %eax
-        jmp     2f
+        jmp     bc_return
 
-1:
-        jnz     2f
-
+bc_child:
         # we're in the child now, call __bionic_clone_entry
         # with the appropriate arguments on the child stack
         # we already placed most of them
         call    __bionic_clone_entry
         hlt
 
-2:
+bc_parent:
+        # we're the parent; nothing to do.
+bc_return:
         popl    %edi
         popl    %esi
         popl    %ebx
diff --git a/libc/arch-x86/bionic/futex_x86.S b/libc/arch-x86/bionic/futex_x86.S
index 096f72c..36a28e8 100644
--- a/libc/arch-x86/bionic/futex_x86.S
+++ b/libc/arch-x86/bionic/futex_x86.S
@@ -19,7 +19,6 @@
     ret
 END(__futex_wait)
 
-
 // int __futex_wake(volatile void *ftx, int count)
 ENTRY(__futex_wake)
     pushl   %ebx
diff --git a/libc/arch-x86/bionic/setjmp.S b/libc/arch-x86/bionic/setjmp.S
index bcb5f9d..c0df647 100644
--- a/libc/arch-x86/bionic/setjmp.S
+++ b/libc/arch-x86/bionic/setjmp.S
@@ -52,7 +52,7 @@
 	call	_C_LABEL(sigblock)
 #endif
 	addl	$4,%esp
-	PIC_EPILOGUE 
+	PIC_EPILOGUE
 
 	movl	4(%esp),%ecx
 	movl	0(%esp),%edx
@@ -65,6 +65,7 @@
 	movl	%eax,24(%ecx)
 	xorl	%eax,%eax
 	ret
+END(setjmp)
 
 ENTRY(longjmp)
 	movl	4(%esp),%edx
@@ -76,7 +77,7 @@
 	call	_C_LABEL(sigsetmask)
 #endif
 	addl	$4,%esp
-	PIC_EPILOGUE 
+	PIC_EPILOGUE
 
 	movl	4(%esp),%edx
 	movl	8(%esp),%eax
@@ -91,3 +92,4 @@
 	incl	%eax
 1:	movl	%ecx,0(%esp)
 	ret
+END(longjmp)
diff --git a/libc/arch-x86/bionic/sigsetjmp.S b/libc/arch-x86/bionic/sigsetjmp.S
index c990a05..70cc6db 100644
--- a/libc/arch-x86/bionic/sigsetjmp.S
+++ b/libc/arch-x86/bionic/sigsetjmp.S
@@ -61,6 +61,7 @@
 	movl	%edi,20(%ecx)
 	xorl	%eax,%eax
 	ret
+END(sigsetjmp)
 
 ENTRY(siglongjmp)
 	movl	4(%esp),%edx
@@ -90,3 +91,4 @@
 	incl	%eax
 2:	movl	%ecx,0(%esp)
 	ret
+END(siglongjmp)
diff --git a/libc/arch-x86/string/bcmp.S b/libc/arch-x86/string/bcmp.S
index a5b46ae..4a88f66 100644
--- a/libc/arch-x86/string/bcmp.S
+++ b/libc/arch-x86/string/bcmp.S
@@ -30,3 +30,4 @@
 L2:	popl	%esi
 	popl	%edi
 	ret
+END(bcmp)
diff --git a/libc/arch-x86/string/bzero.S b/libc/arch-x86/string/bzero.S
index 2ec9c7d..c73a351 100644
--- a/libc/arch-x86/string/bzero.S
+++ b/libc/arch-x86/string/bzero.S
@@ -41,3 +41,4 @@
 
 	popl	%edi
 	ret
+END(bzero)
diff --git a/libc/arch-x86/string/fss.S b/libc/arch-x86/string/ffs.S
similarity index 97%
rename from libc/arch-x86/string/fss.S
rename to libc/arch-x86/string/ffs.S
index 96affab..d819306 100644
--- a/libc/arch-x86/string/fss.S
+++ b/libc/arch-x86/string/ffs.S
@@ -15,3 +15,4 @@
 	.align 2
 L1:	xorl	%eax,%eax		/* clear result */
 	ret
+END(ffs)
diff --git a/libc/arch-x86/string/memchr.S b/libc/arch-x86/string/memchr.S
index d6bcbe6..367c7b4 100644
--- a/libc/arch-x86/string/memchr.S
+++ b/libc/arch-x86/string/memchr.S
@@ -24,3 +24,4 @@
 L1:	xorl	%eax,%eax
 	popl	%edi
 	ret
+END(memchr)
diff --git a/libc/arch-x86/string/memcmp.S b/libc/arch-x86/string/memcmp.S
index 1be189a..3b50530 100644
--- a/libc/arch-x86/string/memcmp.S
+++ b/libc/arch-x86/string/memcmp.S
@@ -41,3 +41,4 @@
 	popl	%esi
 	popl	%edi
 	ret
+END(memcmp)
diff --git a/libc/arch-x86/string/memset.S b/libc/arch-x86/string/memset.S
index 1059ccc..62e6a17 100644
--- a/libc/arch-x86/string/memset.S
+++ b/libc/arch-x86/string/memset.S
@@ -53,3 +53,4 @@
 	popl	%ebx
 	popl	%edi
 	ret
+END(memset)
diff --git a/libc/arch-x86/string/strcat.S b/libc/arch-x86/string/strcat.S
index 60fdd55..c75f38a 100644
--- a/libc/arch-x86/string/strcat.S
+++ b/libc/arch-x86/string/strcat.S
@@ -71,3 +71,4 @@
 L2:	popl	%eax			/* pop destination address */
 	popl	%edi			/* restore edi */
 	ret
+END(strcat)
diff --git a/libc/arch-x86/string/strcmp.S b/libc/arch-x86/string/strcmp.S
index 22ba546..5d3f4fc 100644
--- a/libc/arch-x86/string/strcmp.S
+++ b/libc/arch-x86/string/strcmp.S
@@ -79,3 +79,4 @@
 	movzbl	(%edx),%edx
 	subl	%edx,%eax
 	ret
+END(strcmp)
diff --git a/libc/arch-x86/string/strcpy.S b/libc/arch-x86/string/strcpy.S
index 341eb6c..7d9b87e 100644
--- a/libc/arch-x86/string/strcpy.S
+++ b/libc/arch-x86/string/strcpy.S
@@ -61,3 +61,4 @@
 	jnz	L1
 L2:	popl	%eax			/* pop dst address */
 	ret
+END(strcpy)
diff --git a/libc/arch-x86/string/strlen.S b/libc/arch-x86/string/strlen.S
index 4f04ffc..527e36a 100644
--- a/libc/arch-x86/string/strlen.S
+++ b/libc/arch-x86/string/strlen.S
@@ -18,3 +18,4 @@
 	leal	-1(%ecx),%eax		/* and subtracting one */
 	popl	%edi
 	ret
+END(strlen)
diff --git a/libc/arch-x86/string/strncmp.S b/libc/arch-x86/string/strncmp.S
index 5aa88d7..6649473 100644
--- a/libc/arch-x86/string/strncmp.S
+++ b/libc/arch-x86/string/strncmp.S
@@ -111,3 +111,4 @@
 L4:	xorl	%eax,%eax
 	popl	%ebx
 	ret
+END(strncmp)
diff --git a/libc/arch-x86/string/swab.S b/libc/arch-x86/string/swab.S
index 3055860..2f6cfb2 100644
--- a/libc/arch-x86/string/swab.S
+++ b/libc/arch-x86/string/swab.S
@@ -65,3 +65,4 @@
 L4:	popl	%edi
 	popl	%esi
 	ret
+END(swab)
diff --git a/libc/netbsd/net/getnameinfo.c b/libc/netbsd/net/getnameinfo.c
index 16ff0cb..ade5240 100644
--- a/libc/netbsd/net/getnameinfo.c
+++ b/libc/netbsd/net/getnameinfo.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: getnameinfo.c,v 1.43 2006/02/17 15:58:26 ginsbach Exp $	*/
+/*	$NetBSD: getnameinfo.c,v 1.53 2012/09/26 23:13:00 christos Exp $	*/
 /*	$KAME: getnameinfo.c,v 1.45 2000/09/25 22:43:56 itojun Exp $	*/
 
 /*
@@ -47,33 +47,27 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: getnameinfo.c,v 1.43 2006/02/17 15:58:26 ginsbach Exp $");
+__RCSID("$NetBSD: getnameinfo.c,v 1.53 2012/09/26 23:13:00 christos Exp $");
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 #include <net/if.h>
-#if defined(ANDROID_CHANGES) && defined(AF_LINK)
-#include <net/if_dl.h>
-#endif
 #include <net/if_ieee1394.h>
 #include <net/if_types.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include "arpa_nameser.h"
 #include <assert.h>
 #include <limits.h>
 #include <netdb.h>
-#ifdef ANDROID_CHANGES
+#include "arpa_nameser.h"
 #include "resolv_private.h"
 #include <sys/system_properties.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <sys/un.h>
 #include <errno.h>
-#else
-#include <resolv.h>
-#endif
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
 #include <stddef.h>
 #include <string.h>
 
@@ -98,29 +92,15 @@
 	u_short	si_port;
 };
 
-#if defined(ANDROID_CHANGES)
-static int getnameinfo_inet __P((const struct sockaddr *, socklen_t, char *,
-    socklen_t, char *, socklen_t, int, const char*));
-#else
-static int getnameinfo_inet __P((const struct sockaddr *, socklen_t, char *,
-    socklen_t, char *, socklen_t, int));
-#endif
-
+static int getnameinfo_inet(const struct sockaddr *, socklen_t, char *,
+    socklen_t, char *, socklen_t, int, const char*);
 #ifdef INET6
-static int ip6_parsenumeric __P((const struct sockaddr *, const char *, char *,
-				 socklen_t, int));
-static int ip6_sa2str __P((const struct sockaddr_in6 *, char *, size_t,
-				 int));
+static int ip6_parsenumeric(const struct sockaddr *, const char *, char *,
+				 socklen_t, int);
+static int ip6_sa2str(const struct sockaddr_in6 *, char *, size_t, int);
 #endif
-#if defined(ANDROID_CHANGES) && defined(AF_LINK)
-static int getnameinfo_link __P((const struct sockaddr *, socklen_t, char *,
-    socklen_t, char *, socklen_t, int));
-#endif
-static int hexname __P((const u_int8_t *, size_t, char *, socklen_t));
-
-// This should be synchronized to ResponseCode.h
-static const int DnsProxyQueryResult = 222;
-
+static int getnameinfo_local(const struct sockaddr *, socklen_t, char *,
+    socklen_t, char *, socklen_t, int);
 
 /*
  * Top-level getnameinfo() code.  Look at the address family, and pick an
@@ -128,33 +108,51 @@
  */
 int getnameinfo(const struct sockaddr* sa, socklen_t salen, char* host, size_t hostlen, char* serv, size_t servlen, int flags)
 {
-#ifdef ANDROID_CHANGES
 	return android_getnameinfoforiface(sa, salen, host, hostlen, serv, servlen, flags, NULL);
 }
 
 int android_getnameinfoforiface(const struct sockaddr* sa, socklen_t salen, char* host, size_t hostlen, char* serv, size_t servlen, int flags, const char* iface)
 {
-#endif /* ANDROID_CHANGES */
 	switch (sa->sa_family) {
 	case AF_INET:
 	case AF_INET6:
 		return getnameinfo_inet(sa, salen, host, hostlen,
-#ifdef ANDROID_CHANGES
 				serv, servlen, flags, iface);
-#else
+	case AF_LOCAL:
+		return getnameinfo_local(sa, salen, host, hostlen,
 		    serv, servlen, flags);
-#endif
-#if defined(ANDROID_CHANGES) && defined(AF_LINK)
-	case AF_LINK:
-		return getnameinfo_link(sa, salen, host, hostlen,
-				serv, servlen, flags);
-#endif
 	default:
 		return EAI_FAMILY;
 	}
 }
 
-#ifdef ANDROID_CHANGES
+/*
+ * getnameinfo_local():
+ * Format an local address into a printable format.
+ */
+/* ARGSUSED */
+static int
+getnameinfo_local(const struct sockaddr *sa, socklen_t salen,
+    char *host, socklen_t hostlen, char *serv, socklen_t servlen,
+    int flags __attribute__((unused)))
+{
+       const struct sockaddr_un *sun =
+           (const struct sockaddr_un *)(const void *)sa;
+
+       if (salen < (socklen_t) offsetof(struct sockaddr_un, sun_path)) {
+           return EAI_FAMILY;
+       }
+
+       if (serv != NULL && servlen > 0)
+               serv[0] = '\0';
+
+       if (host && hostlen > 0)
+               strlcpy(host, sun->sun_path,
+                   MIN((socklen_t) sizeof(sun->sun_path) + 1, hostlen));
+
+       return 0;
+}
+
 /* On success length of the host name is returned. A return
  * value of 0 means there's no host name associated with
  * the address. On failure -1 is returned in which case
@@ -172,33 +170,16 @@
 	if (nameBuf) strncpy(nameBuf, hostResult->h_name, nameBufLen);
 	return lengthResult;
 }
-#endif
+
 /*
  * getnameinfo_inet():
  * Format an IPv4 or IPv6 sockaddr into a printable string.
  */
-#ifdef ANDROID_CHANGES
 static int
-getnameinfo_inet(sa, salen, host, hostlen, serv, servlen, flags, iface)
-	const struct sockaddr *sa;
-	socklen_t salen;
-	char *host;
-	socklen_t hostlen;
-	char *serv;
-	socklen_t servlen;
-	int flags;
-	const char* iface;
-#else
-static int
-getnameinfo_inet(sa, salen, host, hostlen, serv, servlen, flags)
-	const struct sockaddr *sa;
-	socklen_t salen;
-	char *host;
-	socklen_t hostlen;
-	char *serv;
-	socklen_t servlen;
-	int flags;
-#endif
+getnameinfo_inet(const struct sockaddr* sa, socklen_t salen,
+       char *host, socklen_t hostlen,
+       char *serv, socklen_t servlen,
+       int flags, const char* iface)
 {
 	const struct afd *afd;
 	struct servent *sp;
@@ -206,7 +187,7 @@
 	u_short port;
 	int family, i;
 	const char *addr;
-	u_int32_t v4a;
+	uint32_t v4a;
 	char numserv[512];
 	char numaddr[512];
 
@@ -217,11 +198,6 @@
 	if (sa == NULL)
 		return EAI_FAIL;
 
-#ifdef BSD4_4
-	if (sa->sa_len != salen)
-		return EAI_FAIL;
-#endif
-
 	family = sa->sa_family;
 	for (i = 0; afdl[i].a_af; i++)
 		if (afdl[i].a_af == family) {
@@ -231,8 +207,11 @@
 	return EAI_FAMILY;
 
  found:
-	if (salen != afd->a_socklen)
-		return EAI_FAIL;
+	// http://b/1889275: callers should be allowed to provide too much
+	// space, but not too little.
+	if (salen < afd->a_socklen) {
+		return EAI_FAMILY;
+	}
 
 	/* network byte order */
 	port = ((const struct sockinet *)(const void *)sa)->si_port;
@@ -266,7 +245,7 @@
 
 	switch (sa->sa_family) {
 	case AF_INET:
-		v4a = (u_int32_t)
+		v4a = (uint32_t)
 		    ntohl(((const struct sockaddr_in *)
 		    (const void *)sa)->sin_addr.s_addr);
 		if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
@@ -338,7 +317,6 @@
 			break;
 		}
 	} else {
-#ifdef ANDROID_CHANGES
 		struct hostent android_proxy_hostent;
 		char android_proxy_buf[MAXDNAME];
 
@@ -352,12 +330,9 @@
 		} else {
 			hp = android_gethostbyaddrforiface(addr, afd->a_addrlen, afd->a_af, iface);
 		}
-#else
-		hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
-#endif
 
 		if (hp) {
-#if defined(ANDROID_CHANGES) && defined(AF_LINK)
+#if 0
 			/*
 			 * commented out, since "for local host" is not
 			 * implemented here - see RFC2553 p30
@@ -402,12 +377,8 @@
 
 #ifdef INET6
 static int
-ip6_parsenumeric(sa, addr, host, hostlen, flags)
-	const struct sockaddr *sa;
-	const char *addr;
-	char *host;
-	socklen_t hostlen;
-	int flags;
+ip6_parsenumeric(const struct sockaddr *sa, const char *addr, char *host,
+       socklen_t hostlen, int flags)
 {
 	size_t numaddrlen;
 	char numaddr[512];
@@ -416,9 +387,6 @@
 	assert(addr != NULL);
 	assert(host != NULL);
 
-	if (hostlen < 0)
-		return EAI_OVERFLOW;
-
 	if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr)) == NULL)
 		return EAI_SYSTEM;
 
@@ -450,11 +418,7 @@
 
 /* ARGSUSED */
 static int
-ip6_sa2str(sa6, buf, bufsiz, flags)
-	const struct sockaddr_in6 *sa6;
-	char *buf;
-	size_t bufsiz;
-	int flags;
+ip6_sa2str(const struct sockaddr_in6 *sa6, char *buf, size_t bufsiz, int flags)
 {
 	unsigned int ifindex;
 	const struct in6_addr *a6;
@@ -493,109 +457,3 @@
 		return n;
 }
 #endif /* INET6 */
-
-
-#if defined(ANDROID_CHANGES) && defined(AF_LINK)
-/*
- * getnameinfo_link():
- * Format a link-layer address into a printable format, paying attention to
- * the interface type.
- */
-/* ARGSUSED */
-static int
-getnameinfo_link(const struct sockaddr *sa, socklen_t salen,
-    char *host, socklen_t hostlen, char *serv, socklen_t servlen,
-    int flags)
-{
-	const struct sockaddr_dl *sdl =
-	    (const struct sockaddr_dl *)(const void *)sa;
-	const struct ieee1394_hwaddr *iha;
-	int n;
-
-	if (serv != NULL && servlen > 0)
-		*serv = '\0';
-
-	if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && sdl->sdl_slen == 0) {
-		n = snprintf(host, hostlen, "link#%u", sdl->sdl_index);
-		if (n < 0 || (socklen_t) n > hostlen) {
-			*host = '\0';
-			return EAI_MEMORY;
-		}
-		return 0;
-	}
-
-	switch (sdl->sdl_type) {
-#ifdef IFT_ECONET
-	case IFT_ECONET:
-		if (sdl->sdl_alen < 2)
-			return EAI_FAMILY;
-		if (CLLADDR(sdl)[1] == 0)
-			n = snprintf(host, hostlen, "%u", CLLADDR(sdl)[0]);
-		else
-			n = snprintf(host, hostlen, "%u.%u",
-			    CLLADDR(sdl)[1], CLLADDR(sdl)[0]);
-		if (n < 0 || (socklen_t) n >= hostlen) {
-			*host = '\0';
-			return EAI_MEMORY;
-		} else
-			return 0;
-#endif
-	case IFT_IEEE1394:
-		if (sdl->sdl_alen < sizeof(iha->iha_uid))
-			return EAI_FAMILY;
-		iha =
-		    (const struct ieee1394_hwaddr *)(const void *)CLLADDR(sdl);
-		return hexname(iha->iha_uid, sizeof(iha->iha_uid),
-		    host, hostlen);
-	/*
-	 * The following have zero-length addresses.
-	 * IFT_ATM	(net/if_atmsubr.c)
-	 * IFT_FAITH	(net/if_faith.c)
-	 * IFT_GIF	(net/if_gif.c)
-	 * IFT_LOOP	(net/if_loop.c)
-	 * IFT_PPP	(net/if_ppp.c, net/if_spppsubr.c)
-	 * IFT_SLIP	(net/if_sl.c, net/if_strip.c)
-	 * IFT_STF	(net/if_stf.c)
-	 * IFT_L2VLAN	(net/if_vlan.c)
-	 * IFT_PROPVIRTUAL (net/if_bridge.h>
-	 */
-	/*
-	 * The following use IPv4 addresses as link-layer addresses:
-	 * IFT_OTHER	(net/if_gre.c)
-	 */
-	case IFT_ARCNET: /* default below is believed correct for all these. */
-	case IFT_ETHER:
-	case IFT_FDDI:
-	case IFT_HIPPI:
-	case IFT_ISO88025:
-	default:
-		return hexname((const u_int8_t *)CLLADDR(sdl),
-		    (size_t)sdl->sdl_alen, host, hostlen);
-	}
-}
-#endif
-
-static int
-hexname(cp, len, host, hostlen)
-	const u_int8_t *cp;
-	char *host;
-	size_t len;
-	socklen_t hostlen;
-{
-	int n;
-	size_t i;
-	char *outp = host;
-
-	*outp = '\0';
-	for (i = 0; i < len; i++) {
-		n = snprintf(outp, hostlen, "%s%02x",
-		    i ? ":" : "", cp[i]);
-		if (n < 0 || (socklen_t) n >= hostlen) {
-			*host = '\0';
-			return EAI_MEMORY;
-		}
-		outp += n;
-		hostlen -= n;
-	}
-	return 0;
-}
diff --git a/libc/netbsd/net/getservbyname_r.c b/libc/netbsd/net/getservbyname_r.c
deleted file mode 100644
index fb6dc52..0000000
--- a/libc/netbsd/net/getservbyname_r.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*	$NetBSD: getservbyname_r.c,v 1.3 2005/04/18 19:39:45 kleink Exp $	*/
-
-/*
- * Copyright (c) 1983, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)getservbyname.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: getservbyname_r.c,v 1.3 2005/04/18 19:39:45 kleink Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#include <assert.h>
-#include <netdb.h>
-#include <string.h>
-
-#include "servent.h"
-
-struct servent *
-getservbyname_r(const char *name, const char *proto, struct servent *sp,
-    struct servent_data *sd)
-{
-	struct servent *s;
-	char **cp;
-
-	assert(name != NULL);
-	/* proto may be NULL */
-
-	setservent_r(sd->stayopen, sd);
-	while ((s = getservent_r(sp, sd)) != NULL) {
-		if (strcmp(name, s->s_name) == 0)
-			goto gotname;
-		for (cp = s->s_aliases; *cp; cp++)
-			if (strcmp(name, *cp) == 0)
-				goto gotname;
-		continue;
-gotname:
-		if (proto == NULL || strcmp(s->s_proto, proto) == 0)
-			break;
-	}
-	if (!sd->stayopen)
-		if (sd->fp != NULL) {
-			(void)fclose(sd->fp);
-			sd->fp = NULL;
-		}
-	return s;
-}
diff --git a/libc/netbsd/net/getservbyport_r.c b/libc/netbsd/net/getservbyport_r.c
deleted file mode 100644
index 6fe4293..0000000
--- a/libc/netbsd/net/getservbyport_r.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*	$NetBSD: getservbyport_r.c,v 1.3 2005/04/18 19:39:45 kleink Exp $	*/
-
-/*
- * Copyright (c) 1983, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)getservbyport.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: getservbyport_r.c,v 1.3 2005/04/18 19:39:45 kleink Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#include <netdb.h>
-#include <string.h>
-
-#include "servent.h"
-
-struct servent *
-getservbyport_r(int port, const char *proto, struct servent *sp,
-    struct servent_data *sd)
-{
-	struct servent *s;
-
-	setservent_r(sd->stayopen, sd);
-	while ((s = getservent_r(sp, sd)) != NULL) {
-		if (s->s_port != port)
-			continue;
-		if (proto == NULL || strcmp(s->s_proto, proto) == 0)
-			break;
-	}
-	if (!sd->stayopen)
-		if (sd->fp != NULL) {
-			(void)fclose(sd->fp);
-			sd->fp = NULL;
-		}
-	return s;
-}
diff --git a/libc/netbsd/net/getservent_r.c b/libc/netbsd/net/getservent_r.c
deleted file mode 100644
index 1668759..0000000
--- a/libc/netbsd/net/getservent_r.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*	$NetBSD: getservent_r.c,v 1.5 2005/04/18 19:39:45 kleink Exp $	*/
-
-/*
- * Copyright (c) 1983, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)getservent.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: getservent_r.c,v 1.5 2005/04/18 19:39:45 kleink Exp $");
-#endif
-#endif /* LIBC_SCCS and not lint */
-
-#include <netdb.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <netinet/in.h>
-
-#include "servent.h"
-
-void
-setservent_r(int f, struct servent_data *sd)
-{
-	if (sd->fp == NULL)
-		sd->fp = fopen(_PATH_SERVICES, "r");
-	else
-		rewind(sd->fp);
-	sd->stayopen |= f;
-}
-
-void
-endservent_r(struct servent_data *sd)
-{
-	if (sd->fp) {
-		(void)fclose(sd->fp);
-		sd->fp = NULL;
-	}
-	if (sd->aliases) {
-		free(sd->aliases);
-		sd->aliases = NULL;
-		sd->maxaliases = 0;
-	}
-	if (sd->line) {
-		free(sd->line);
-		sd->line = NULL;
-	}
-	sd->stayopen = 0;
-}
-
-struct servent *
-getservent_r(struct servent *sp, struct servent_data *sd)
-{
-	char *p, *cp, **q;
-	size_t i = 0;
-	int oerrno;
-
-	if (sd->fp == NULL && (sd->fp = fopen(_PATH_SERVICES, "r")) == NULL)
-		return NULL;
-
-	for (;;) {
-		if (sd->line)
-			free(sd->line);
-//		sd->line = fparseln(sd->fp, NULL, NULL, NULL, FPARSELN_UNESCALL);
-		fprintf(stderr, "*** FIX ME! getservent_r() is going to fail!!!\n");
-		sd->line = NULL;
-		if (sd->line == NULL)
-			return NULL;
-		sp->s_name = p = sd->line;
-		p = strpbrk(p, " \t");
-		if (p == NULL)
-			continue;
-		*p++ = '\0';
-		while (*p == ' ' || *p == '\t')
-			p++;
-		cp = strpbrk(p, ",/");
-		if (cp == NULL)
-			continue;
-		*cp++ = '\0';
-		sp->s_port = htons((u_short)atoi(p));
-		sp->s_proto = cp;
-		if (sd->aliases == NULL) {
-			sd->maxaliases = 10;
-			sd->aliases = malloc(sd->maxaliases * sizeof(char *));
-			if (sd->aliases == NULL) {
-				oerrno = errno;
-				endservent_r(sd);
-				errno = oerrno;
-				return NULL;
-			}
-		}
-		q = sp->s_aliases = sd->aliases;
-		cp = strpbrk(cp, " \t");
-		if (cp != NULL)
-			*cp++ = '\0';
-		while (cp && *cp) {
-			if (*cp == ' ' || *cp == '\t') {
-				cp++;
-				continue;
-			}
-			if (i == sd->maxaliases - 2) {
-				sd->maxaliases *= 2;
-				q = realloc(q,
-				    sd->maxaliases * sizeof(char *));
-				if (q == NULL) {
-					oerrno = errno;
-					endservent_r(sd);
-					errno = oerrno;
-					return NULL;
-				}
-				sp->s_aliases = sd->aliases = q;
-			}
-			q[i++] = cp;
-			cp = strpbrk(cp, " \t");
-			if (cp != NULL)
-				*cp++ = '\0';
-		}
-		q[i] = NULL;
-		return sp;
-	}
-}
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 4dd66c0..dfbb142 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -79,54 +79,19 @@
 #define BIONIC_TLS_SLOTS 64
 
 /* set the Thread Local Storage, must contain at least BIONIC_TLS_SLOTS pointers */
-extern void __init_tls(void**  tls, void*  thread_info);
+extern void __init_tls(void** tls, void* thread_info);
 
 /* syscall only, do not call directly */
-extern int __set_tls(void *ptr);
+extern int __set_tls(void* ptr);
 
 /* get the TLS */
-#ifdef __arm__
-/* The standard way to get the TLS is to call a kernel helper
- * function (i.e. a function provided at a fixed address in a
- * "magic page" mapped in all user-space address spaces ), which
- * contains the most appropriate code path for the target device.
- *
- * However, for performance reasons, we're going to use our own
- * machine code for the system's C shared library.
- *
- * We cannot use this optimization in the static version of the
- * C library, because we don't know where the corresponding code
- * is going to run.
- */
-#  ifdef LIBC_STATIC
-
-/* Use the kernel helper in static C library. */
-  typedef volatile void* (__kernel_get_tls_t)(void);
-#    define __get_tls() (*(__kernel_get_tls_t *)0xffff0fe0)()
-
-#  else /* !LIBC_STATIC */
-/* Use optimized code path.
- * Note that HAVE_ARM_TLS_REGISTER is build-specific
- * (it must match your kernel configuration)
- */
-#    ifdef HAVE_ARM_TLS_REGISTER
- /* We can read the address directly from a coprocessor
-  * register, which avoids touching the data cache
-  * completely.
-  */
-#      define __get_tls() \
+#if defined(__arm__)
+# define __get_tls() \
     ({ register unsigned int __val asm("r0"); \
        asm ("mrc p15, 0, r0, c13, c0, 3" : "=r"(__val) ); \
        (volatile void*)__val; })
-#    else /* !HAVE_ARM_TLS_REGISTER */
- /* The kernel provides the address of the TLS at a fixed
-  * address of the magic page too.
-  */
-#      define __get_tls() ( *((volatile void **) 0xffff0ff0) )
-#    endif
-#  endif /* !LIBC_STATIC */
 #elif defined(__mips__)
-#    define __get_tls() \
+# define __get_tls() \
     ({ register unsigned int __val asm("v1");   \
         asm (                                   \
             "   .set    push\n"                 \
@@ -136,12 +101,17 @@
             : "=r"(__val)                       \
             );                                  \
         (volatile void*)__val; })
+#elif defined(__i386__)
+# define __get_tls() \
+    ({ register void* __val; \
+       asm ("movl %%gs:0, %0" : "=r"(__val)); \
+       (volatile void*) __val; })
 #else
-extern void*  __get_tls( void );
+#error unsupported architecture
 #endif
 
 /* return the stack base and size, used by our malloc debugger */
-extern void*  __get_stack_base(int  *p_stack_size);
+extern void* __get_stack_base(int* p_stack_size);
 
 __END_DECLS
 
diff --git a/linker/Android.mk b/linker/Android.mk
index ea43191..d1773a8 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -23,15 +23,9 @@
         -fvisibility=hidden \
         -Wall -Wextra -Werror
 
-# We need to access Bionic private headers in the linker...
+# We need to access Bionic private headers in the linker.
 LOCAL_CFLAGS += -I$(LOCAL_PATH)/../libc/
 
-# ...one of which is <private/bionic_tls.h>, for which we
-# need HAVE_ARM_TLS_REGISTER.
-ifeq ($(TARGET_ARCH)-$(ARCH_ARM_HAVE_TLS_REGISTER),arm-true)
-    LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
-endif
-
 ifeq ($(TARGET_ARCH),arm)
     LOCAL_CFLAGS += -DANDROID_ARM_LINKER
 endif
diff --git a/tests/Android.mk b/tests/Android.mk
index 8138cff..1e4ef59 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -63,6 +63,7 @@
     getcwd_test.cpp \
     libgen_test.cpp \
     math_test.cpp \
+    netdb_test.cpp \
     pthread_test.cpp \
     regex_test.cpp \
     signal_test.cpp \
@@ -70,6 +71,7 @@
     stdio_test.cpp \
     stdlib_test.cpp \
     string_test.cpp \
+    strings_test.cpp \
     stubs_test.cpp \
     unistd_test.cpp \
 
@@ -124,7 +126,6 @@
 # implementation for testing the tests themselves.
 ifeq ($(HOST_OS)-$(HOST_ARCH),linux-x86)
 include $(CLEAR_VARS)
-LOCAL_CXX := /usr/bin/g++ # Avoid the host prebuilt so we test the real glibc.
 LOCAL_MODULE := bionic-unit-tests-glibc
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_CFLAGS += $(test_c_flags)
diff --git a/tests/netdb_test.cpp b/tests/netdb_test.cpp
new file mode 100644
index 0000000..33f6c01
--- /dev/null
+++ b/tests/netdb_test.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+TEST(netdb, getaddrinfo_NULL_hints) {
+  addrinfo* ai = NULL;
+  ASSERT_EQ(0, getaddrinfo("localhost", "9999", NULL, &ai));
+  freeaddrinfo(ai);
+}
+
+TEST(netdb, getnameinfo_salen) {
+  sockaddr_storage ss;
+  memset(&ss, 0, sizeof(ss));
+  sockaddr* sa = reinterpret_cast<sockaddr*>(&ss);
+  char tmp[16];
+
+  ss.ss_family = AF_INET;
+  socklen_t too_much = sizeof(ss);
+  socklen_t just_right = sizeof(sockaddr_in);
+  socklen_t too_little = sizeof(sockaddr_in) - 1;
+
+  ASSERT_EQ(0, getnameinfo(sa, too_much, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
+  ASSERT_STREQ("0.0.0.0", tmp);
+  ASSERT_EQ(0, getnameinfo(sa, just_right, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
+  ASSERT_STREQ("0.0.0.0", tmp);
+  ASSERT_EQ(EAI_FAMILY, getnameinfo(sa, too_little, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
+
+  ss.ss_family = AF_INET6;
+  just_right = sizeof(sockaddr_in6);
+  too_little = sizeof(sockaddr_in6) - 1;
+  too_much = just_right + 1;
+
+  ASSERT_EQ(0, getnameinfo(sa, too_much, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
+  ASSERT_STREQ("::", tmp);
+  ASSERT_EQ(0, getnameinfo(sa, just_right, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
+  ASSERT_STREQ("::", tmp);
+  ASSERT_EQ(EAI_FAMILY, getnameinfo(sa, too_little, tmp, sizeof(tmp), NULL, 0, NI_NUMERICHOST));
+}
diff --git a/tests/strings_test.cpp b/tests/strings_test.cpp
new file mode 100644
index 0000000..5200859
--- /dev/null
+++ b/tests/strings_test.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 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 <errno.h>
+#include <strings.h>
+
+TEST(strings, ffs) {
+  ASSERT_EQ( 0, ffs(0x00000000));
+  ASSERT_EQ( 1, ffs(0x00000001));
+  ASSERT_EQ( 6, ffs(0x00000020));
+  ASSERT_EQ(11, ffs(0x00000400));
+  ASSERT_EQ(16, ffs(0x00008000));
+  ASSERT_EQ(17, ffs(0x00010000));
+  ASSERT_EQ(22, ffs(0x00200000));
+  ASSERT_EQ(27, ffs(0x04000000));
+  ASSERT_EQ(32, ffs(0x80000000));
+}