am 81d79f9f: am 962dcb22: am fed58049: Merge "libc: Fix PTHREAD_RWLOCK_INITIALIZER"

* commit '81d79f9fb38d9ae8a5711f5774aa5a1516f6cc26':
  libc: Fix PTHREAD_RWLOCK_INITIALIZER
  Proxy getnameinfo through netd
  Updated gcc 4.4.3 IA toolchain doesn't require the .ctors list
  Convert cname lenght before use
diff --git a/libc/arch-x86/bionic/crtbegin_dynamic.S b/libc/arch-x86/bionic/crtbegin_dynamic.S
index 88e7e6a..0a7bc62 100644
--- a/libc/arch-x86/bionic/crtbegin_dynamic.S
+++ b/libc/arch-x86/bionic/crtbegin_dynamic.S
@@ -66,14 +66,7 @@
 1:  .long   __PREINIT_ARRAY__
     .long   __INIT_ARRAY__
     .long   __FINI_ARRAY__
-    .long   __CTOR_LIST__
-      
-# the .ctors section contains a list of pointers to "constructor"
-# functions that need to be called in order during C library initialization,
-# just before the program is being run. This is a C++ requirement
-#
-# the last entry shall be 0, and is defined in crtend.S
-#
+
 	.section .preinit_array, "aw"
 	.globl __PREINIT_ARRAY__
 __PREINIT_ARRAY__:
@@ -89,9 +82,4 @@
 __FINI_ARRAY__:
 	.long -1
 
-	.section .ctors, "aw"
-	.globl __CTOR_LIST__
-__CTOR_LIST__:
-	.long -1
-
 #include "__dso_handle.S"
diff --git a/libc/arch-x86/bionic/crtbegin_so.S b/libc/arch-x86/bionic/crtbegin_so.S
index d879fef..b3a01b5 100644
--- a/libc/arch-x86/bionic/crtbegin_so.S
+++ b/libc/arch-x86/bionic/crtbegin_so.S
@@ -5,15 +5,6 @@
     call __cxa_finalize
     ret
 
-/* we put the _init() function here in case the user files for the shared
- * libs want to drop things into .init section.
- * We then will call our ctors from crtend_so.o */
-.section .init
-.align 4
-.type _init, @function
-.globl _init
-_init:
-
 .section .init_array, "aw"
 .align 4
 .type __INIT_ARRAY__, @object
@@ -29,11 +20,4 @@
     .long -1
     .long _on_dlclose
 
-.section .ctors, "aw"
-.align 4
-.type __CTOR_LIST__, @object
-.globl __CTOR_LIST__
-__CTOR_LIST__:
-        .long -1
-
 #include "__dso_handle.S"
diff --git a/libc/arch-x86/bionic/crtbegin_static.S b/libc/arch-x86/bionic/crtbegin_static.S
index 3f8446e..d5c2430 100644
--- a/libc/arch-x86/bionic/crtbegin_static.S
+++ b/libc/arch-x86/bionic/crtbegin_static.S
@@ -65,7 +65,6 @@
 1:  .long   __PREINIT_ARRAY__
     .long   __INIT_ARRAY__
     .long   __FINI_ARRAY__
-    .long   __CTOR_LIST__
 
 	.section .preinit_array, "aw"
 	.globl __PREINIT_ARRAY__
@@ -82,9 +81,4 @@
 __FINI_ARRAY__:
 	.long -1
 
-	.section .ctors, "aw"
-	.globl __CTOR_LIST__
-__CTOR_LIST__:
-	.long -1
-
 #include "__dso_handle.S"
diff --git a/libc/arch-x86/bionic/crtend.S b/libc/arch-x86/bionic/crtend.S
index 7f5fb66..884ba8b 100644
--- a/libc/arch-x86/bionic/crtend.S
+++ b/libc/arch-x86/bionic/crtend.S
@@ -1,4 +1,3 @@
-	
 	.section .preinit_array, "aw"
 	.long 0
 
@@ -7,7 +6,3 @@
 
 	.section .fini_array, "aw"
 	.long 0
-
-	.section .ctors, "aw"
-	.long 0
-
diff --git a/libc/arch-x86/bionic/crtend_so.S b/libc/arch-x86/bionic/crtend_so.S
index 7fb2280..8c9d419 100644
--- a/libc/arch-x86/bionic/crtend_so.S
+++ b/libc/arch-x86/bionic/crtend_so.S
@@ -1,44 +1,3 @@
-.text
-.align 4
-.type __bionic_call_ctors, @function
-
-/*
- * The CTORS_LIST is marked by -1 (start) and 0 (end).
- * We mark the end of the .ctors section with the __CTOR_END__ section so
- * that we can just iterate backwards from it until we hit -1 and execute
- * all the function pointers. This seems to be the way to do it for SVR4
- * derived systems.
- */
-__bionic_call_ctors:
-    pushl  %esi
-    mov    $__CTOR_END__, %esi
-
-0:
-    /* now grab the next function pointer and check if its -1. If not,
-     * call it, otherwise we're done. We use %esi since it's callee saved.
-     */
-    subl    $4, %esi
-    mov     (%esi), %eax
-    cmp     $0xffffffff, %eax
-    je      1f
-    call    *%eax
-    jmp     0b
-
-1:
-    /* we're done */
-    popl    %esi
-    ret
-
-.section .init
-.align 4
-    call __bionic_call_ctors
-    ret
-
-.section .ctors, "aw", @progbits
-.align 4
-.type __CTOR_END__, @object
-__CTOR_END__:
-    .long 0
 
 .section .init_array, "aw"
     .long 0
diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h
index 6016d4d..35050a1 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -35,7 +35,9 @@
     void (**preinit_array)(void);
     void (**init_array)(void);
     void (**fini_array)(void);
+#ifndef __i386__
     void (**ctors_array)(void);
+#endif
 } structors_array_t;
 
 extern void __libc_init_common(uintptr_t *elfdata);
diff --git a/libc/bionic/libc_init_static.c b/libc/bionic/libc_init_static.c
index 3634c7b..a2c11a9 100644
--- a/libc/bionic/libc_init_static.c
+++ b/libc/bionic/libc_init_static.c
@@ -75,8 +75,10 @@
     /* pre-init array. */
     call_array(structors->preinit_array);
 
+#ifndef __i386__
     /* .ctors section initializers, for non-arm-eabi ABIs */
     call_array(structors->ctors_array);
+#endif
 
     // call static constructors
     call_array(structors->init_array);
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index a43e47c..27e13e4 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -233,7 +233,7 @@
     void*            reserved[4];  /* for future extensibility */
 } pthread_rwlock_t;
 
-#define PTHREAD_RWLOCK_INITIALIZER  { PTHREAD_MUTEX_INITIALIZER, 0, NULL, 0, 0 }
+#define PTHREAD_RWLOCK_INITIALIZER  { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0, 0, 0, { NULL, NULL, NULL, NULL } }
 
 int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
 int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
diff --git a/libc/netbsd/net/getnameinfo.c b/libc/netbsd/net/getnameinfo.c
index 3666443..0b9fe51 100644
--- a/libc/netbsd/net/getnameinfo.c
+++ b/libc/netbsd/net/getnameinfo.c
@@ -64,6 +64,11 @@
 #include <netdb.h>
 #ifdef ANDROID_CHANGES
 #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
@@ -124,7 +129,93 @@
 	}
 }
 
+#ifdef ANDROID_CHANGES
+/* 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
+ * normal execution flow shall continue. */
+static int
+android_gethostbyaddr_proxy(struct hostent* hp, const char *addr, socklen_t addrLen, int addrFamily) {
 
+	int sock;
+	const int one = 1;
+	struct sockaddr_un proxy_addr;
+	const char* cache_mode = getenv("ANDROID_DNS_MODE");
+	FILE* proxy = NULL;
+	int result = -1;
+
+	if (cache_mode != NULL && strcmp(cache_mode, "local") == 0) {
+		// Don't use the proxy in local mode.  This is used by the
+		// proxy itself.
+		return -1;
+	}
+
+	// Temporary cautious hack to disable the DNS proxy for processes
+	// requesting special treatment.  Ideally the DNS proxy should
+	// accomodate these apps, though.
+	char propname[PROP_NAME_MAX];
+	char propvalue[PROP_VALUE_MAX];
+	snprintf(propname, sizeof(propname), "net.dns1.%d", getpid());
+	if (__system_property_get(propname, propvalue) > 0) {
+		return -1;
+	}
+	// create socket
+	sock = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (sock < 0) {
+		return -1;
+	}
+
+	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+	memset(&proxy_addr, 0, sizeof(proxy_addr));
+	proxy_addr.sun_family = AF_UNIX;
+	strlcpy(proxy_addr.sun_path, "/dev/socket/dnsproxyd",
+			sizeof(proxy_addr.sun_path));
+	if (TEMP_FAILURE_RETRY(connect(sock, (const struct sockaddr*) &proxy_addr,
+							sizeof(proxy_addr))) != 0) {
+		close(sock);
+		return -1;
+	}
+
+	// send request to DnsProxyListener
+	proxy = fdopen(sock,"r+");
+	if (proxy == NULL) {
+		goto exit;
+	}
+
+	if (fprintf(proxy, "gethostbyaddr %s %d %d", addr, addrLen, addrFamily) < 0) {
+		goto exit;
+	}
+
+	// literal NULL byte at end, required by FrameworkListener
+	if (fputc(0, proxy) == EOF || fflush(proxy) != 0) {
+		goto exit;
+	}
+
+	result = 0;
+	uint32_t name_len;
+	if (fread(&name_len, sizeof(name_len), 1, proxy) != 1) {
+		goto exit;
+	}
+
+	name_len = ntohl(name_len);
+	if (name_len <= 0) {
+		goto exit;
+	}
+
+	if (fread(hp->h_name, name_len, 1, proxy) != 1) {
+		goto exit;
+	}
+
+	result = name_len;
+
+ exit:
+	if (proxy != NULL) {
+		fclose(proxy);
+	}
+
+	return result;
+}
+#endif
 /*
  * getnameinfo_inet():
  * Format an IPv4 or IPv6 sockaddr into a printable string.
@@ -277,7 +368,21 @@
 			break;
 		}
 	} else {
+#ifdef ANDROID_CHANGES
+		struct hostent android_proxy_hostent;
+		char android_proxy_buf[MAXDNAME];
+		android_proxy_hostent.h_name = android_proxy_buf;
+
+		int hostnamelen = android_gethostbyaddr_proxy(&android_proxy_hostent,
+				addr, afd->a_addrlen, afd->a_af);
+		if (hostnamelen >= 0) {
+			hp = (hostnamelen > 0) ? &android_proxy_hostent : NULL;
+		} else {
+			hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
+		}
+#else
 		hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
+#endif
 
 		if (hp) {
 #if 0
diff --git a/linker/arch/x86/begin.S b/linker/arch/x86/begin.S
index d8a39ca..b4427e0 100644
--- a/linker/arch/x86/begin.S
+++ b/linker/arch/x86/begin.S
@@ -44,9 +44,3 @@
         popl   %esp
         jmp    *%eax
 
-.section .ctors, "wa"
-.globl __CTOR_LIST__
-
-__CTOR_LIST__:
-        .long -1
-