Reconcile with ics-mr1-release

Change-Id: I62bace5c4272d043a51d3f0f698556716838aa51
diff --git a/libc/Android.mk b/libc/Android.mk
index 49c8731..225d14f 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -510,11 +510,8 @@
   endif
 else # !arm
   ifeq ($(TARGET_ARCH),x86)
-    libc_crt_target_cflags := -m32
-
-    # Enable recent IA friendly memory routines (such as for Atom)
-    # These will not work on the earlier x86 machines
-    libc_common_cflags += -mtune=i686 -DUSE_SSSE3 -DUSE_SSE2
+    libc_crt_target_cflags :=
+    # TARGET_GLOBAL_CFLAGS from build/core/combo/TARGET_linux-x86.mk sets all required flags.
   endif # x86
 endif # !arm
 
diff --git a/libc/arch-x86/bionic/__set_tls.c b/libc/arch-x86/bionic/__set_tls.c
index 48b55f0..e5e43b5 100755
--- a/libc/arch-x86/bionic/__set_tls.c
+++ b/libc/arch-x86/bionic/__set_tls.c
@@ -60,6 +60,8 @@
     0
 };
 
+static pthread_mutex_t  _tls_desc_lock = PTHREAD_MUTEX_INITIALIZER;
+
 struct _thread_area_head {
     void *self;
 };
@@ -71,6 +73,7 @@
 {
     int   rc, segment;
 
+    pthread_mutex_lock(&_tls_desc_lock);
     _tls_desc.base_addr = (unsigned long)ptr;
 
     /* We also need to write the location of the tls to ptr[0] */
@@ -88,6 +91,8 @@
     asm __volatile__ (
         "   movw %w0, %%gs" :: "q"(segment)
     );
+    pthread_mutex_unlock(&_tls_desc_lock);
+
     return 0;
 }
 
diff --git a/libc/arch-x86/bionic/clone.S b/libc/arch-x86/bionic/clone.S
index b9b0957..8abb7c8 100644
--- a/libc/arch-x86/bionic/clone.S
+++ b/libc/arch-x86/bionic/clone.S
@@ -22,6 +22,7 @@
         movl    %eax, -8(%ecx)
         movl    %ecx, -4(%ecx)
 
+        subl    $16, %ecx
         movl    $__NR_clone, %eax
         int     $0x80
         test    %eax, %eax
@@ -39,7 +40,6 @@
         # we're in the child thread now, call __thread_entry
         # with the appropriate arguments on the child stack
         # we already placed most of them
-        subl    $16, %esp
         jmp     __thread_entry
         hlt
 
diff --git a/libc/bionic/cpuacct.c b/libc/bionic/cpuacct.c
index 7317073..1321d0e 100644
--- a/libc/bionic/cpuacct.c
+++ b/libc/bionic/cpuacct.c
@@ -30,16 +30,19 @@
 #include <errno.h>
 #include <sys/stat.h>
 #include "cpuacct.h"
+#include <fcntl.h>
 
 int cpuacct_add(uid_t uid)
 {
     int count;
-    FILE *fp;
+    int fd;
     char buf[80];
+    ssize_t n;
+    int ret = 0;
 
     count = snprintf(buf, sizeof(buf), "/acct/uid/%d/tasks", uid);
-    fp = fopen(buf, "w+");
-    if (!fp) {
+    fd = open(buf, O_RDWR | O_CREAT, 0666);
+    if (fd == -1) {
         /* Note: sizeof("tasks") returns 6, which includes the NULL char */
         buf[count - sizeof("tasks")] = 0;
         if (mkdir(buf, 0775) < 0)
@@ -47,14 +50,19 @@
 
         /* Note: sizeof("tasks") returns 6, which includes the NULL char */
         buf[count - sizeof("tasks")] = '/';
-        fp = fopen(buf, "w+");
+        fd = open(buf, O_RDWR | O_CREAT, 0666);
     }
-    if (!fp)
+    if (fd == -1)
         return -errno;
 
-    fprintf(fp, "0");
-    if (fclose(fp))
+    n = TEMP_FAILURE_RETRY(write(fd, "0", 1));
+    if (n < 0)
+        ret = -errno;
+    else if (n == 0)
+        ret = -EIO;
+
+    if (TEMP_FAILURE_RETRY(close(fd)) == -1)
         return -errno;
 
-    return 0;
+    return ret;
 }
diff --git a/libc/bionic/malloc_debug_leak.c b/libc/bionic/malloc_debug_leak.c
index 0a3a68d..e0bcee9 100644
--- a/libc/bionic/malloc_debug_leak.c
+++ b/libc/bionic/malloc_debug_leak.c
@@ -263,7 +263,7 @@
 // =============================================================================
 
 #define CHK_FILL_FREE           0xef
-#define CHK_SENTINEL_VALUE      0xeb
+#define CHK_SENTINEL_VALUE      (char)0xeb
 #define CHK_SENTINEL_HEAD_SIZE  16
 #define CHK_SENTINEL_TAIL_SIZE  16
 #define CHK_OVERHEAD_SIZE       (   CHK_SENTINEL_HEAD_SIZE +    \
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c
index 1da2ec9..3435d21 100644
--- a/libc/bionic/pthread.c
+++ b/libc/bionic/pthread.c
@@ -571,6 +571,7 @@
     void*                stack_base = thread->attr.stack_base;
     int                  stack_size = thread->attr.stack_size;
     int                  user_stack = (thread->attr.flags & PTHREAD_ATTR_FLAG_USER_STACK) != 0;
+    sigset_t mask;
 
     // call the cleanup handlers first
     while (thread->cleanup_stack) {
@@ -613,6 +614,10 @@
         pthread_mutex_unlock(&gThreadListLock);
     }
 
+    sigfillset(&mask);
+    sigdelset(&mask, SIGSEGV);
+    (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+
     // destroy the thread stack
     if (user_stack)
         _exit_thread((int)retval);
@@ -1856,7 +1861,21 @@
     return ret;
 }
 
-extern int __rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t);
+/* Despite the fact that our kernel headers define sigset_t explicitly
+ * as a 32-bit integer, the kernel system call really expects a 64-bit
+ * bitmap for the signal set, or more exactly an array of two-32-bit
+ * values (see $KERNEL/arch/$ARCH/include/asm/signal.h for details).
+ *
+ * Unfortunately, we cannot fix the sigset_t definition without breaking
+ * the C library ABI, so perform a little runtime translation here.
+ */
+typedef union {
+    sigset_t   bionic;
+    uint32_t   kernel[2];
+} kernel_sigset_t;
+
+/* this is a private syscall stub */
+extern int __rt_sigprocmask(int, const kernel_sigset_t *, kernel_sigset_t *, size_t);
 
 int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
 {
@@ -1865,16 +1884,31 @@
      */
     int ret, old_errno = errno;
 
-    /* Use NSIG which corresponds to the number of signals in
-     * our 32-bit sigset_t implementation. As such, this function, or
-     * anything that deals with sigset_t cannot manage real-time signals
-     * (signo >= 32). We might want to introduce sigset_rt_t as an
-     * extension to do so in the future.
-     */
-    ret = __rt_sigprocmask(how, set, oset, NSIG / 8);
+    /* We must convert *set into a kernel_sigset_t */
+    kernel_sigset_t  in_set, *in_set_ptr;
+    kernel_sigset_t  out_set;
+
+    in_set.kernel[0] = in_set.kernel[1] = 0;
+    out_set.kernel[0] = out_set.kernel[1] = 0;
+
+    /* 'in_set_ptr' is the second parameter to __rt_sigprocmask. It must be NULL
+     * if 'set' is NULL to ensure correct semantics (which in this case would
+     * be to ignore 'how' and return the current signal set into 'oset'.
+      */
+    if (set == NULL) {
+        in_set_ptr = NULL;
+    } else {
+        in_set.bionic = *set;
+        in_set_ptr = &in_set;
+    }
+
+    ret = __rt_sigprocmask(how, in_set_ptr, &out_set, sizeof(kernel_sigset_t));
     if (ret < 0)
         ret = errno;
 
+    if (oset)
+        *oset = out_set.bionic;
+
     errno = old_errno;
     return ret;
 }
diff --git a/libc/string/index.c b/libc/string/index.c
index fb0492f..81bfba4 100644
--- a/libc/string/index.c
+++ b/libc/string/index.c
@@ -34,7 +34,7 @@
 index(const char *p, int ch)
 {
 	for (;; ++p) {
-		if (*p == ch)
+		if (*p == (char) ch)
 			return((char *)p);
 		if (!*p)
 			return((char *)NULL);
diff --git a/libc/string/memrchr.c b/libc/string/memrchr.c
index a533fef..aeb5643 100644
--- a/libc/string/memrchr.c
+++ b/libc/string/memrchr.c
@@ -35,10 +35,10 @@
         const char*  q = p + n;
 
         while (1) {
-            q--; if (q < p || q[0] == c) break;
-            q--; if (q < p || q[0] == c) break;
-            q--; if (q < p || q[0] == c) break;
-            q--; if (q < p || q[0] == c) break;
+            q--; if (q < p || q[0] == (char) c) break;
+            q--; if (q < p || q[0] == (char) c) break;
+            q--; if (q < p || q[0] == (char) c) break;
+            q--; if (q < p || q[0] == (char) c) break;
         }
         if (q >= p)
             return (void*)q;
diff --git a/libc/string/strchr.c b/libc/string/strchr.c
index 31ba4e2..9b4332c 100644
--- a/libc/string/strchr.c
+++ b/libc/string/strchr.c
@@ -34,7 +34,7 @@
 strchr(const char *p, int ch)
 {
 	for (;; ++p) {
-		if (*p == ch)
+		if (*p == (char) ch)
 			return((char *)p);
 		if (!*p)
 			return((char *)NULL);
diff --git a/libc/string/strrchr.c b/libc/string/strrchr.c
index 4918f82..10c07e6 100644
--- a/libc/string/strrchr.c
+++ b/libc/string/strrchr.c
@@ -36,7 +36,7 @@
 	char *save;
 
 	for (save = NULL;; ++p) {
-		if (*p == ch)
+		if (*p == (char) ch)
 			save = (char *)p;
 		if (!*p)
 			return(save);
diff --git a/libc/unistd/pathconf.c b/libc/unistd/pathconf.c
index 032f918..26b580f 100644
--- a/libc/unistd/pathconf.c
+++ b/libc/unistd/pathconf.c
@@ -70,13 +70,12 @@
     };
     int  nn = 0;
 
-    for (;;) {
-        if ( known64[nn] == EOL_MAGIC )
-            return 32;
-
-        if ( known64[nn] == s->f_type )
+    for (; known64[nn] != EOL_MAGIC; ++nn) {
+        if (known64[nn] == s->f_type) {
             return 64;
+        }
     }
+    return 32;
 }
 
 
@@ -99,12 +98,10 @@
     };
     int   nn = 0;
 
-    for (;;) {
-        if ( knownMax[nn].type == EOL_MAGIC )
-            return LINK_MAX;
-
-        if ( knownMax[nn].type == s->f_type )
+    for (; knownMax[nn].type != EOL_MAGIC; ++nn) {
+        if (knownMax[nn].type == s->f_type) {
             return knownMax[nn].max;
+        }
     }
     return LINK_MAX;
 }
@@ -121,12 +118,12 @@
     };
     int  nn = 0;
 
-    for (;;) {
-        if (knownNoSymlinks[nn] == 0)
-            return 1;
-        if (knownNoSymlinks[nn] == s->f_type)
+    for (; knownNoSymlinks[nn] != EOL_MAGIC; ++nn) {
+        if (knownNoSymlinks[nn] == s->f_type) {
             return 0;
+        }
     }
+    return 1;
 }
 
 static long
diff --git a/linker/linker.c b/linker/linker.c
index e0a8a18..17008f8 100644
--- a/linker/linker.c
+++ b/linker/linker.c
@@ -707,7 +707,11 @@
     if (hdr->e_ident[EI_MAG3] != ELFMAG3) return -1;
 
     /* TODO: Should we verify anything else in the header? */
-
+#ifdef ANDROID_ARM_LINKER
+    if (hdr->e_machine != EM_ARM) return -1;
+#elif defined(ANDROID_X86_LINKER)
+    if (hdr->e_machine != EM_386) return -1;
+#endif
     return 0;
 }