Merge "Simplify three copyright headers."
diff --git a/libc/Android.mk b/libc/Android.mk
index d41f8af..54047c8 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -941,10 +941,6 @@
 LOCAL_CFLAGS := $(libc_common_cflags) \
     -Wframe-larger-than=2048 \
 
-# memcpy.S, memchr.S, etc. do not compile with Clang.
-LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
-LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
-
 LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
 LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
 LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
@@ -972,10 +968,6 @@
 LOCAL_CFLAGS := $(libc_common_cflags) \
     -Wframe-larger-than=2048 \
 
-# memcpy.S, memchr.S, etc. do not compile with Clang.
-LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
-LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
-
 LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
 LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
 LOCAL_C_INCLUDES := $(libc_common_c_includes) bionic/libstdc++/include
@@ -1024,10 +1016,6 @@
 LOCAL_CFLAGS := $(libc_common_cflags) \
     -Wframe-larger-than=2048 \
 
-# memcpy.S, memchr.S, etc. do not compile with Clang.
-LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
-LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
-
 LOCAL_CONLYFLAGS := $(libc_common_conlyflags)
 LOCAL_CPPFLAGS := $(libc_common_cppflags) -Wold-style-cast
 LOCAL_C_INCLUDES := $(libc_common_c_includes)
@@ -1379,11 +1367,10 @@
 # We'd really like to do this for all architectures, but since this wasn't done
 # before, these symbols must continue to be exported on LP32 for binary
 # compatibility.
-# TODO: disabled for http://b/20065774.
-#LOCAL_LDFLAGS_64 := -Wl,--exclude-libs,libgcc.a
+LOCAL_LDFLAGS_64 := -Wl,--exclude-libs,libgcc.a
 
 # TODO: This is to work around b/19059885. Remove after root cause is fixed
-LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
+LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
 
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 $(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_arch_dynamic_src_files))
@@ -1513,7 +1500,7 @@
 LOCAL_CPPFLAGS := $(libc_common_cppflags)
 
 # TODO: This is to work around b/19059885. Remove after root cause is fixed
-LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
+LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
 
 LOCAL_SRC_FILES := $(libstdcxx_common_src_files)
 LOCAL_MODULE:= libstdc++
diff --git a/libc/arch-arm/cortex-a9/bionic/memset.S b/libc/arch-arm/cortex-a9/bionic/memset.S
index 299f5a2..8ee6ac2 100644
--- a/libc/arch-arm/cortex-a9/bionic/memset.S
+++ b/libc/arch-arm/cortex-a9/bionic/memset.S
@@ -35,6 +35,7 @@
  */
 
     .fpu    neon
+    .syntax unified
 
 ENTRY(__memset_chk)
         cmp         r2, r3
@@ -100,9 +101,9 @@
 1:      bge         2f
         vst1.32     {d0[0]}, [r0]!
 2:      movs        ip, r2, lsl #31
-        strmib      r1, [r0], #1
-        strcsb      r1, [r0], #1
-        strcsb      r1, [r0], #1
+        strbmi      r1, [r0], #1
+        strbcs      r1, [r0], #1
+        strbcs      r1, [r0], #1
         ldmfd       sp!, {r0}
         bx          lr
 END(memset)
@@ -131,11 +132,11 @@
         orr         r1, r1, r1, lsr #16
 
         movs        r12, r3, lsl #31
-        strcsb      r1, [r0], #1    /* can't use strh (alignment unknown) */
-        strcsb      r1, [r0], #1
-        strmib      r1, [r0], #1
+        strbcs      r1, [r0], #1    /* can't use strh (alignment unknown) */
+        strbcs      r1, [r0], #1
+        strbmi      r1, [r0], #1
         subs        r2, r2, r3
-        ldmlsfd     sp!, {r0, r4-r7, lr}   /* return */
+        popls       {r0, r4-r7, lr}   /* return */
         bxls        lr
 
         /* align the destination to a cache-line */
@@ -155,9 +156,9 @@
 
         /* conditionally writes 0 to 7 words (length in r3) */
         movs        r3, r3, lsl #28
-        stmcsia     r0!, {r1, lr}
-        stmcsia     r0!, {r1, lr}
-        stmmiia     r0!, {r1, lr}
+        stmcs       r0!, {r1, lr}
+        stmcs       r0!, {r1, lr}
+        stmmi       r0!, {r1, lr}
         movs        r3, r3, lsl #2
         strcs       r1, [r0], #4
 
@@ -172,13 +173,13 @@
 
         /* conditionally stores 0 to 31 bytes */
         movs        r2, r2, lsl #28
-        stmcsia     r0!, {r1,r3,r12,lr}
-        stmmiia     r0!, {r1, lr}
+        stmcs       r0!, {r1,r3,r12,lr}
+        stmmi       r0!, {r1, lr}
         movs        r2, r2, lsl #2
         strcs       r1, [r0], #4
-        strmih      r1, [r0], #2
+        strhmi      r1, [r0], #2
         movs        r2, r2, lsl #2
-        strcsb      r1, [r0]
+        strbcs      r1, [r0]
         ldmfd       sp!, {r0, r4-r7, lr}
         bx          lr
 END(__memset_large_copy)
diff --git a/libc/arch-arm/generic/bionic/memcmp.S b/libc/arch-arm/generic/bionic/memcmp.S
index 70a2a58..c78dbd4 100644
--- a/libc/arch-arm/generic/bionic/memcmp.S
+++ b/libc/arch-arm/generic/bionic/memcmp.S
@@ -40,6 +40,8 @@
  * Optimized memcmp() for Cortex-A9.
  */
 
+.syntax unified
+
 ENTRY(memcmp)
         pld         [r0, #(CACHE_LINE_SIZE * 0)]
         pld         [r0, #(CACHE_LINE_SIZE * 1)]
@@ -161,25 +163,25 @@
         eors        r0, r0, ip
         ldreq       r0, [r4], #4
         ldreq       ip, [r1, #4]!
-        eoreqs      r0, r0, lr
+        eorseq      r0, r0, lr
         ldreq       r0, [r4], #4
         ldreq       lr, [r1, #4]!
-        eoreqs      r0, r0, ip
+        eorseq      r0, r0, ip
         ldreq       r0, [r4], #4
         ldreq       ip, [r1, #4]!
-        eoreqs      r0, r0, lr
+        eorseq      r0, r0, lr
         ldreq       r0, [r4], #4
         ldreq       lr, [r1, #4]!
-        eoreqs      r0, r0, ip
+        eorseq      r0, r0, ip
         ldreq       r0, [r4], #4
         ldreq       ip, [r1, #4]!
-        eoreqs      r0, r0, lr
+        eorseq      r0, r0, lr
         ldreq       r0, [r4], #4
         ldreq       lr, [r1, #4]!
-        eoreqs      r0, r0, ip
+        eorseq      r0, r0, ip
         ldreq       r0, [r4], #4
         ldreq       ip, [r1, #4]!
-        eoreqs      r0, r0, lr
+        eorseq      r0, r0, lr
         bne         2f
         subs        r2, r2, #32
         bhs         0b
@@ -263,17 +265,17 @@
         ldreq       lr, [r1], #4
         ldreq       r0, [r4], #4
         orreq       ip, ip, lr, lsl #16
-        eoreqs      r0, r0, ip
+        eorseq      r0, r0, ip
         moveq       ip, lr, lsr #16
         ldreq       lr, [r1], #4
         ldreq       r0, [r4], #4
         orreq       ip, ip, lr, lsl #16
-        eoreqs      r0, r0, ip
+        eorseq      r0, r0, ip
         moveq       ip, lr, lsr #16
         ldreq       lr, [r1], #4
         ldreq       r0, [r4], #4
         orreq       ip, ip, lr, lsl #16
-        eoreqs      r0, r0, ip
+        eorseq      r0, r0, ip
         bne         7f
         subs        r2, r2, #16
         bhs         6b
@@ -317,7 +319,7 @@
         ldreq       r7, [r1], #4
         ldreq       r0, [r4], #4
         orreq       ip, ip, r7, lsl r6
-        eoreqs      r0, r0, ip
+        eorseq      r0, r0, ip
         bne         7f
         subs        r2, r2, #8
         bhs         6b
diff --git a/libc/arch-arm/generic/bionic/memcpy.S b/libc/arch-arm/generic/bionic/memcpy.S
index b0c79ab..ea5a399 100644
--- a/libc/arch-arm/generic/bionic/memcpy.S
+++ b/libc/arch-arm/generic/bionic/memcpy.S
@@ -37,6 +37,8 @@
          * so we have to preserve R0.
          */
 
+         .syntax unified
+
 ENTRY(__memcpy_chk)
         cmp         r2, r3
         bhi         __memcpy_chk_fail
@@ -81,12 +83,12 @@
          */
         movs        r12, r3, lsl #31
         sub         r2, r2, r3      /* we know that r3 <= r2 because r2 >= 4 */
-        ldrmib      r3, [r1], #1
-        ldrcsb      r4, [r1], #1
-        ldrcsb      r12,[r1], #1
-        strmib      r3, [r0], #1
-        strcsb      r4, [r0], #1
-        strcsb      r12,[r0], #1
+        ldrbmi      r3, [r1], #1
+        ldrbcs      r4, [r1], #1
+        ldrbcs      r12,[r1], #1
+        strbmi      r3, [r0], #1
+        strbcs      r4, [r0], #1
+        strbcs      r12,[r0], #1
 
 .Lsrc_aligned:
 
@@ -109,10 +111,10 @@
 
         /* conditionally copies 0 to 7 words (length in r3) */
         movs        r12, r3, lsl #28
-        ldmcsia     r1!, {r4, r5, r6, r7}   /* 16 bytes */
-        ldmmiia     r1!, {r8, r9}           /*  8 bytes */
-        stmcsia     r0!, {r4, r5, r6, r7}
-        stmmiia     r0!, {r8, r9}
+        ldmcs       r1!, {r4, r5, r6, r7}   /* 16 bytes */
+        ldmmi       r1!, {r8, r9}           /*  8 bytes */
+        stmcs       r0!, {r4, r5, r6, r7}
+        stmmi       r0!, {r8, r9}
         tst         r3, #0x4
         ldrne       r10,[r1], #4            /*  4 bytes */
         strne       r10,[r0], #4
@@ -177,18 +179,18 @@
 
         /* conditionnaly copies 0 to 31 bytes */
         movs        r12, r2, lsl #28
-        ldmcsia     r1!, {r4, r5, r6, r7}   /* 16 bytes */
-        ldmmiia     r1!, {r8, r9}           /*  8 bytes */
-        stmcsia     r0!, {r4, r5, r6, r7}
-        stmmiia     r0!, {r8, r9}
+        ldmcs       r1!, {r4, r5, r6, r7}   /* 16 bytes */
+        ldmmi       r1!, {r8, r9}           /*  8 bytes */
+        stmcs       r0!, {r4, r5, r6, r7}
+        stmmi       r0!, {r8, r9}
         movs        r12, r2, lsl #30
         ldrcs       r3, [r1], #4            /*  4 bytes */
-        ldrmih      r4, [r1], #2            /*  2 bytes */
+        ldrhmi      r4, [r1], #2            /*  2 bytes */
         strcs       r3, [r0], #4
-        strmih      r4, [r0], #2
+        strhmi      r4, [r0], #2
         tst         r2, #0x1
-        ldrneb      r3, [r1]                /*  last byte  */
-        strneb      r3, [r0]
+        ldrbne      r3, [r1]                /*  last byte  */
+        strbne      r3, [r0]
 
         /* we're done! restore everything and return */
 1:      ldmfd       sp!, {r5-r11}
@@ -228,11 +230,11 @@
          * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
          */
         movs        r5, r5, lsl #31
-        strmib      r3, [r0], #1
+        strbmi      r3, [r0], #1
         movmi       r3, r3, lsr #8
-        strcsb      r3, [r0], #1
+        strbcs      r3, [r0], #1
         movcs       r3, r3, lsr #8
-        strcsb      r3, [r0], #1
+        strbcs      r3, [r0], #1
         movcs       r3, r3, lsr #8
 
         cmp         r2, #4
@@ -363,23 +365,23 @@
 .Lpartial_word_tail:
         /* we have a partial word in the input buffer */
         movs        r5, lr, lsl #(31-3)
-        strmib      r3, [r0], #1
+        strbmi      r3, [r0], #1
         movmi       r3, r3, lsr #8
-        strcsb      r3, [r0], #1
+        strbcs      r3, [r0], #1
         movcs       r3, r3, lsr #8
-        strcsb      r3, [r0], #1
+        strbcs      r3, [r0], #1
 
         /* Refill spilled registers from the stack. Don't update sp. */
         ldmfd       sp, {r5-r11}
 
 .Lcopy_last_3_and_return:
         movs        r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
-        ldrmib      r2, [r1], #1
-        ldrcsb      r3, [r1], #1
-        ldrcsb      r12,[r1]
-        strmib      r2, [r0], #1
-        strcsb      r3, [r0], #1
-        strcsb      r12,[r0]
+        ldrbmi      r2, [r1], #1
+        ldrbcs      r3, [r1], #1
+        ldrbcs      r12,[r1]
+        strbmi      r2, [r0], #1
+        strbcs      r3, [r0], #1
+        strbcs      r12,[r0]
 
         /* we're done! restore sp and spilled registers and return */
         add         sp,  sp, #28
diff --git a/libc/arch-arm/generic/bionic/memset.S b/libc/arch-arm/generic/bionic/memset.S
index be35de9..d17a9c4 100644
--- a/libc/arch-arm/generic/bionic/memset.S
+++ b/libc/arch-arm/generic/bionic/memset.S
@@ -35,6 +35,8 @@
          * memset() returns its first argument.
          */
 
+         .syntax unified
+
 ENTRY(__memset_chk)
         cmp         r2, r3
         bls         done
@@ -76,11 +78,11 @@
         orr         r1, r1, r1, lsr #16
 
         movs        r12, r3, lsl #31
-        strcsb      r1, [r0], #1    /* can't use strh (alignment unknown) */
-        strcsb      r1, [r0], #1
-        strmib      r1, [r0], #1
+        strbcs      r1, [r0], #1    /* can't use strh (alignment unknown) */
+        strbcs      r1, [r0], #1
+        strbmi      r1, [r0], #1
         subs        r2, r2, r3
-        ldmlsfd     sp!, {r0, r4-r7, lr}    /* return */
+        popls       {r0, r4-r7, lr}    /* return */
         bxls        lr
 
         /* align the destination to a cache-line */
@@ -100,9 +102,9 @@
 
         /* conditionally writes 0 to 7 words (length in r3) */
         movs        r3, r3, lsl #28
-        stmcsia     r0!, {r1, lr}
-        stmcsia     r0!, {r1, lr}
-        stmmiia     r0!, {r1, lr}
+        stmcs       r0!, {r1, lr}
+        stmcs       r0!, {r1, lr}
+        stmmi       r0!, {r1, lr}
         movs        r3, r3, lsl #2
         strcs       r1, [r0], #4
 
@@ -117,13 +119,13 @@
 
         /* conditionally stores 0 to 31 bytes */
         movs        r2, r2, lsl #28
-        stmcsia     r0!, {r1,r3,r12,lr}
-        stmmiia     r0!, {r1, lr}
+        stmcs       r0!, {r1,r3,r12,lr}
+        stmmi       r0!, {r1, lr}
         movs        r2, r2, lsl #2
         strcs       r1, [r0], #4
-        strmih      r1, [r0], #2
+        strhmi      r1, [r0], #2
         movs        r2, r2, lsl #2
-        strcsb      r1, [r0]
+        strbcs      r1, [r0]
         ldmfd       sp!, {r0, r4-r7, lr}
         bx          lr
 END(memset)
diff --git a/libc/arch-arm/generic/bionic/strcpy.S b/libc/arch-arm/generic/bionic/strcpy.S
index 802a62d..89ea098 100644
--- a/libc/arch-arm/generic/bionic/strcpy.S
+++ b/libc/arch-arm/generic/bionic/strcpy.S
@@ -32,6 +32,8 @@
 #include <machine/cpu-features.h>
 #include <private/bionic_asm.h>
 
+.syntax unified
+
 ENTRY(strcpy)
 	pld	[r1, #0]
 	eor	r2, r0, r1
@@ -108,15 +110,15 @@
 #ifdef __ARMEB__
 	tst	r2, #0xff00
 	iteet	ne
-	strneh	r2, [ip], #2
+	strhne	r2, [ip], #2
 	lsreq	r2, r2, #8
-	streqb	r2, [ip]
+	strbeq	r2, [ip]
 	tstne	r2, #0xff
 #else
 	tst	r2, #0xff
 	itet	ne
-	strneh	r2, [ip], #2
-	streqb	r2, [ip]
+	strhne	r2, [ip], #2
+	strbeq	r2, [ip]
 	tstne	r2, #0xff00
 #endif
 	bne	5b
diff --git a/libc/arch-arm/krait/bionic/memset.S b/libc/arch-arm/krait/bionic/memset.S
index e9f6431..a4fbe17 100644
--- a/libc/arch-arm/krait/bionic/memset.S
+++ b/libc/arch-arm/krait/bionic/memset.S
@@ -37,6 +37,7 @@
  */
 
     .fpu    neon
+    .syntax unified
 
 ENTRY(__memset_chk)
         cmp         r2, r3
@@ -98,9 +99,9 @@
 1:      bge         2f
         vst1.32     {d0[0]}, [r0]!
 2:      movs        ip, r2, lsl #31
-        strmib      r1, [r0], #1
-        strcsb      r1, [r0], #1
-        strcsb      r1, [r0], #1
+        strbmi      r1, [r0], #1
+        strbcs      r1, [r0], #1
+        strbcs      r1, [r0], #1
         ldmfd       sp!, {r0}
         bx          lr
 END(memset)
diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk
index 6a2f313..470a038 100644
--- a/libc/arch-arm64/arm64.mk
+++ b/libc/arch-arm64/arm64.mk
@@ -40,8 +40,6 @@
     arch-arm64/bionic/syscall.S \
     arch-arm64/bionic/vfork.S \
 
-# Work around for http://b/20065774.
-libc_bionic_src_files_arm64 += arch-arm64/bionic/libgcc_compat.c
 
 libc_crt_target_cflags_arm64 := \
     -I$(LOCAL_PATH)/arch-arm64/include
diff --git a/libc/arch-arm64/bionic/libgcc_compat.c b/libc/arch-arm64/bionic/libgcc_compat.c
deleted file mode 100644
index 2dae3f5..0000000
--- a/libc/arch-arm64/bionic/libgcc_compat.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* STOPSHIP: remove this once the flounder blobs have been rebuilt (http://b/20065774). */
-
-#if !defined(__clang__)
-
-extern void __clear_cache(char*, char*);
-extern char _Unwind_Backtrace;
-extern char _Unwind_GetIP;
-
-void* __bionic_libgcc_compat_symbols[] = {
-    &__clear_cache,
-    &_Unwind_Backtrace,
-    &_Unwind_GetIP,
-};
-
-#endif
diff --git a/libc/arch-arm64/generic/bionic/memchr.S b/libc/arch-arm64/generic/bionic/memchr.S
index e5ea57d..a00dd8d 100644
--- a/libc/arch-arm64/generic/bionic/memchr.S
+++ b/libc/arch-arm64/generic/bionic/memchr.S
@@ -101,7 +101,7 @@
 	and	vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
 	addp	vend.16b, vhas_chr1.16b, vhas_chr2.16b		/* 256->128 */
 	addp	vend.16b, vend.16b, vend.16b			/* 128->64 */
-	mov	synd, vend.2d[0]
+	mov	synd, vend.d[0]
 	/* Clear the soff*2 lower bits */
 	lsl	tmp, soff, #1
 	lsr	synd, synd, tmp
@@ -121,7 +121,7 @@
 	/* Use a fast check for the termination condition */
 	orr	vend.16b, vhas_chr1.16b, vhas_chr2.16b
 	addp	vend.2d, vend.2d, vend.2d
-	mov	synd, vend.2d[0]
+	mov	synd, vend.d[0]
 	/* We're not out of data, loop if we haven't found the character */
 	cbz	synd, .Lloop
 
@@ -131,7 +131,7 @@
 	and	vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
 	addp	vend.16b, vhas_chr1.16b, vhas_chr2.16b		/* 256->128 */
 	addp	vend.16b, vend.16b, vend.16b			/* 128->64 */
-	mov	synd, vend.2d[0]
+	mov	synd, vend.d[0]
 	/* Only do the clear for the last possible block */
 	b.hi	.Ltail
 
diff --git a/libc/arch-arm64/generic/bionic/strchr.S b/libc/arch-arm64/generic/bionic/strchr.S
index 469b83c..b54106d 100644
--- a/libc/arch-arm64/generic/bionic/strchr.S
+++ b/libc/arch-arm64/generic/bionic/strchr.S
@@ -109,7 +109,7 @@
 	addp	vend1.16b, vend1.16b, vend2.16b		// 128->64
 	lsr	tmp1, tmp3, tmp1
 
-	mov	tmp3, vend1.2d[0]
+	mov	tmp3, vend1.d[0]
 	bic	tmp1, tmp3, tmp1	// Mask padding bits.
 	cbnz	tmp1, .Ltail
 
@@ -124,7 +124,7 @@
 	orr	vend2.16b, vhas_nul2.16b, vhas_chr2.16b
 	orr	vend1.16b, vend1.16b, vend2.16b
 	addp	vend1.2d, vend1.2d, vend1.2d
-	mov	tmp1, vend1.2d[0]
+	mov	tmp1, vend1.d[0]
 	cbz	tmp1, .Lloop
 
 	/* Termination condition found.  Now need to establish exactly why
@@ -138,7 +138,7 @@
 	addp	vend1.16b, vend1.16b, vend2.16b		// 256->128
 	addp	vend1.16b, vend1.16b, vend2.16b		// 128->64
 
-	mov	tmp1, vend1.2d[0]
+	mov	tmp1, vend1.d[0]
 .Ltail:
 	/* Count the trailing zeros, by bit reversing...  */
 	rbit	tmp1, tmp1
diff --git a/libc/arch-common/bionic/asm_multiarch.h b/libc/arch-common/bionic/asm_multiarch.h
index 85e1b57..91cb8af 100644
--- a/libc/arch-common/bionic/asm_multiarch.h
+++ b/libc/arch-common/bionic/asm_multiarch.h
@@ -28,9 +28,9 @@
 
 #ifdef __LP64__
 # define ASM_PTR_SIZE(x) .quad x
-# define ASM_ALIGN(x)
+# define ASM_ALIGN_TO_PTR_SIZE .balign 8
 #else
 # define ASM_PTR_SIZE(x) .long x
-# define ASM_ALIGN(x)    .align x
+# define ASM_ALIGN_TO_PTR_SIZE .balign 4
 #endif
 
diff --git a/libc/arch-common/bionic/crtend.S b/libc/arch-common/bionic/crtend.S
index a4cf8de..87d1120 100644
--- a/libc/arch-common/bionic/crtend.S
+++ b/libc/arch-common/bionic/crtend.S
@@ -29,12 +29,15 @@
 #include "asm_multiarch.h"
 
 	.section .preinit_array, "aw"
+	ASM_ALIGN_TO_PTR_SIZE
 	ASM_PTR_SIZE(0)
 
 	.section .init_array, "aw"
+	ASM_ALIGN_TO_PTR_SIZE
 	ASM_PTR_SIZE(0)
 
 	.section .fini_array, "aw"
+	ASM_ALIGN_TO_PTR_SIZE
 	ASM_PTR_SIZE(0)
 
 #if defined(__linux__) && defined(__ELF__)
@@ -42,7 +45,9 @@
 #endif
 #if defined(__i386__) || defined(__x86_64__)
 	.section	.eh_frame,"a",@progbits
-	ASM_ALIGN(4)
+#if defined(__i386__)
+	.balign 4
+#endif
 	.type	__FRAME_END__, @object
 	.size	__FRAME_END__, 4
 __FRAME_END__:
diff --git a/libc/arch-common/bionic/crtend_so.S b/libc/arch-common/bionic/crtend_so.S
index f745109..e7b8cac 100644
--- a/libc/arch-common/bionic/crtend_so.S
+++ b/libc/arch-common/bionic/crtend_so.S
@@ -26,22 +26,14 @@
  * SUCH DAMAGE.
  */
 
-#include "asm_multiarch.h"
-
-#ifndef __arm__
-	.section .init_array, "aw"
-	ASM_PTR_SIZE(0)
-
-	.section .fini_array, "aw"
-	ASM_PTR_SIZE(0)
-#endif
-
 #if defined(__linux__) && defined(__ELF__)
 	.section .note.GNU-stack,"",%progbits
 #endif
 #if defined(__i386__) || defined(__x86_64__)
 	.section	.eh_frame,"a",@progbits
-	ASM_ALIGN(4)
+#if defined(__i386__)
+	.balign 4
+#endif
 	.type	__FRAME_END__, @object
 	.size	__FRAME_END__, 4
 __FRAME_END__:
diff --git a/libc/include/elf.h b/libc/include/elf.h
index dcf01ab..eaad1d3 100644
--- a/libc/include/elf.h
+++ b/libc/include/elf.h
@@ -34,6 +34,11 @@
 
 #include <machine/elf_machdep.h>
 
+#define ELF32_R_INFO(sym, type) ((((Elf32_Word)sym) << 8) | ((type) & 0xff))
+#define ELF64_R_INFO(sym, type) ((((Elf64_Xword)sym) << 32) | ((type) & 0xffffffff))
+
+typedef __s64 Elf32_Sxword;
+
 typedef struct {
   __u32 a_type;
   union {
diff --git a/libc/include/sys/_system_properties.h b/libc/include/sys/_system_properties.h
index 8086020..a0315b5 100644
--- a/libc/include/sys/_system_properties.h
+++ b/libc/include/sys/_system_properties.h
@@ -81,7 +81,6 @@
 #define PROP_PATH_RAMDISK_DEFAULT  "/default.prop"
 #define PROP_PATH_SYSTEM_BUILD     "/system/build.prop"
 #define PROP_PATH_VENDOR_BUILD     "/vendor/build.prop"
-#define PROP_PATH_BOOTIMAGE_BUILD  "/build.prop"
 #define PROP_PATH_LOCAL_OVERRIDE   "/data/local.prop"
 #define PROP_PATH_FACTORY          "/factory/factory.prop"
 
diff --git a/libc/tools/check-symbols.py b/libc/tools/check-symbols.py
index 0922548..a2f2ccb 100755
--- a/libc/tools/check-symbols.py
+++ b/libc/tools/check-symbols.py
@@ -13,9 +13,21 @@
 sys.stderr.write('Checking symbols for arch "%s"...\n' % arch)
 
 def GetSymbols(library, functions_or_variables):
+  global api
+  global arch
+
   api = '9'
   if library == 'libm' and arch == 'arm':
     api = '3'
+
+  # There were no 64-bit ABIs before API level 21.
+  if '64' in arch:
+    api = '21'
+
+  # What GCC calls aarch64, Android calls arm64.
+  if arch == 'aarch64':
+    arch = 'arm64'
+
   path = '%s/development/ndk/platforms/android-%s/arch-%s/symbols/%s.so.%s.txt' % (os.environ['ANDROID_BUILD_TOP'], api, arch, library, functions_or_variables)
   symbols = set()
   for line in open(path, 'r'):
@@ -26,7 +38,11 @@
 def CheckSymbols(library, functions_or_variables):
   expected_symbols = GetSymbols(library, functions_or_variables)
 
-  so_file = '%s/system/lib/%s.so' % (os.environ['ANDROID_PRODUCT_OUT'], library)
+  lib_dir = 'lib'
+  if '64' in arch:
+    lib_dir = 'lib64'
+
+  so_file = '%s/system/%s/%s.so' % (os.environ['ANDROID_PRODUCT_OUT'], lib_dir, library)
 
   # Example readelf output:
   #   264: 0001623c     4 FUNC    GLOBAL DEFAULT    8 cabsf
@@ -38,7 +54,7 @@
   r = re.compile(r' +\d+: [0-9a-f]+ +\d+ (FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)')
 
   actual_symbols = set()
-  for line in subprocess.check_output(['readelf', '--dyn-syms', so_file]).split('\n'):
+  for line in subprocess.check_output(['readelf', '-W', '--dyn-syms', so_file]).split('\n'):
     m = r.match(line)
     if m:
       if m.group(1) == 'FUNC' and functions_or_variables == 'functions':
@@ -54,6 +70,12 @@
     for miss in sorted(missing):
       sys.stderr.write('  %s\n' % miss)
 
+  extra = actual_symbols - expected_symbols
+  if len(extra) > 0:
+    sys.stderr.write('%d extra %s in %s for %s:\n' % (len(extra), functions_or_variables, library, arch))
+    for s in sorted(extra):
+      sys.stderr.write('  %s\n' % s)
+
   return len(missing) == 0
 
 CheckSymbols("libc", "functions")
diff --git a/libc/version_script.txt b/libc/version_script.txt
index 349a2fc..afc5e5c 100644
--- a/libc/version_script.txt
+++ b/libc/version_script.txt
@@ -1,9 +1,4 @@
 LIBC {
-  global:
-    /* Work-around for http://b/20065774. */
-    __clear_cache;
-    _Unwind_Backtrace;
-    _Unwind_GetIP;
   local:
     _ZSt7nothrow;
     _ZdaPv;
diff --git a/libm/Android.mk b/libm/Android.mk
index 6472a15..529dda8 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -514,7 +514,7 @@
 include $(CLEAR_VARS)
 
 # TODO: This is to work around b/19059885. Remove after root cause is fixed
-LOCAL_LDFLAGS_arm := -Wl,--hash-style=sysv
+LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
 
 LOCAL_MODULE := libm
 LOCAL_CLANG := $(libm_clang)
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 7d8b266..c3c9029 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -252,7 +252,7 @@
 
   soinfo *prev = nullptr, *trav;
 
-  TRACE("name %s: freeing soinfo @ %p", si->get_soname(), si);
+  TRACE("name %s: freeing soinfo @ %p", si->get_realpath(), si);
 
   for (trav = solist; trav != nullptr; trav = trav->next) {
     if (trav == si) {
@@ -263,7 +263,7 @@
 
   if (trav == nullptr) {
     // si was not in solist
-    DL_ERR("name \"%s\"@%p is not in solist!", si->get_soname(), si);
+    DL_ERR("name \"%s\"@%p is not in solist!", si->get_realpath(), si);
     return;
   }
 
@@ -428,7 +428,7 @@
 
     if (verdef->vd_version != 1) {
       DL_ERR("unsupported verdef[%zd] vd_version: %d (expected 1) library: %s",
-          i, verdef->vd_version, si->get_soname());
+          i, verdef->vd_version, si->get_realpath());
       return false;
     }
 
@@ -498,7 +498,7 @@
     return s->st_shndx != SHN_UNDEF;
   } else if (ELF_ST_BIND(s->st_info) != STB_LOCAL) {
     DL_WARN("unexpected ST_BIND value: %d for '%s' in '%s'",
-        ELF_ST_BIND(s->st_info), si->get_string(s->st_name), si->get_soname());
+        ELF_ST_BIND(s->st_info), si->get_string(s->st_name), si->get_realpath());
   }
 
   return false;
@@ -531,12 +531,12 @@
   *symbol_index = 0;
 
   TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p (gnu)",
-      symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
+      symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
 
   // test against bloom filter
   if ((1 & (bloom_word >> (hash % bloom_mask_bits)) & (bloom_word >> (h2 % bloom_mask_bits))) == 0) {
     TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
-        symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
+        symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
 
     return true;
   }
@@ -546,7 +546,7 @@
 
   if (n == 0) {
     TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
-        symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
+        symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
 
     return true;
   }
@@ -574,7 +574,7 @@
         strcmp(get_string(s->st_name), symbol_name.get_name()) == 0 &&
         is_symbol_global_and_defined(this, s)) {
       TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
-          symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(s->st_value),
+          symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(s->st_value),
           static_cast<size_t>(s->st_size));
       *symbol_index = n;
       return true;
@@ -582,7 +582,7 @@
   } while ((gnu_chain_[n++] & 1) == 0);
 
   TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p",
-             symbol_name.get_name(), get_soname(), reinterpret_cast<void*>(base));
+             symbol_name.get_name(), get_realpath(), reinterpret_cast<void*>(base));
 
   return true;
 }
@@ -593,7 +593,7 @@
   uint32_t hash = symbol_name.elf_hash();
 
   TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p h=%x(elf) %zd",
-             symbol_name.get_name(), get_soname(),
+             symbol_name.get_name(), get_realpath(),
              reinterpret_cast<void*>(base), hash, hash % nbucket_);
 
   ElfW(Versym) verneed = 0;
@@ -614,7 +614,7 @@
         strcmp(get_string(s->st_name), symbol_name.get_name()) == 0 &&
         is_symbol_global_and_defined(this, s)) {
       TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
-                 symbol_name.get_name(), get_soname(),
+                 symbol_name.get_name(), get_realpath(),
                  reinterpret_cast<void*>(s->st_value),
                  static_cast<size_t>(s->st_size));
       *symbol_index = n;
@@ -623,7 +623,7 @@
   }
 
   TRACE_TYPE(LOOKUP, "NOT FOUND %s in %s@%p %x %zd",
-             symbol_name.get_name(), get_soname(),
+             symbol_name.get_name(), get_realpath(),
              reinterpret_cast<void*>(base), hash, hash % nbucket_);
 
   *symbol_index = 0;
@@ -703,7 +703,7 @@
    * relocations for -Bsymbolic linked dynamic executables.
    */
   if (si_from->has_DT_SYMBOLIC) {
-    DEBUG("%s: looking up %s in local scope (DT_SYMBOLIC)", si_from->get_soname(), name);
+    DEBUG("%s: looking up %s in local scope (DT_SYMBOLIC)", si_from->get_realpath(), name);
     if (!si_from->find_symbol_by_name(symbol_name, vi, &s)) {
       return false;
     }
@@ -718,7 +718,7 @@
     bool error = false;
     global_group.visit([&](soinfo* global_si) {
       DEBUG("%s: looking up %s in %s (from global group)",
-          si_from->get_soname(), name, global_si->get_soname());
+          si_from->get_realpath(), name, global_si->get_realpath());
       if (!global_si->find_symbol_by_name(symbol_name, vi, &s)) {
         error = true;
         return false;
@@ -747,7 +747,7 @@
       }
 
       DEBUG("%s: looking up %s in %s (from local group)",
-          si_from->get_soname(), name, local_si->get_soname());
+          si_from->get_realpath(), name, local_si->get_realpath());
       if (!local_si->find_symbol_by_name(symbol_name, vi, &s)) {
         error = true;
         return false;
@@ -769,8 +769,8 @@
   if (s != nullptr) {
     TRACE_TYPE(LOOKUP, "si %s sym %s s->st_value = %p, "
                "found in %s, base = %p, load bias = %p",
-               si_from->get_soname(), name, reinterpret_cast<void*>(s->st_value),
-               (*si_found_in)->get_soname(), reinterpret_cast<void*>((*si_found_in)->base),
+               si_from->get_realpath(), name, reinterpret_cast<void*>(s->st_value),
+               (*si_found_in)->get_realpath(), reinterpret_cast<void*>((*si_found_in)->base),
                reinterpret_cast<void*>((*si_found_in)->load_bias));
   }
 
@@ -1498,7 +1498,7 @@
   }
 
   if (!root->can_unload()) {
-    TRACE("not unloading '%s' - the binary is flagged with NODELETE", root->get_soname());
+    TRACE("not unloading '%s' - the binary is flagged with NODELETE", root->get_realpath());
     return;
   }
 
@@ -1521,7 +1521,9 @@
       if (si->has_min_version(0)) {
         soinfo* child = nullptr;
         while ((child = si->get_children().pop_front()) != nullptr) {
-          TRACE("%s@%p needs to unload %s@%p", si->get_soname(), si, child->get_soname(), child);
+          TRACE("%s@%p needs to unload %s@%p", si->get_realpath(), si,
+              child->get_realpath(), child);
+
           if (local_unload_list.contains(child)) {
             continue;
           } else if (child->is_linked() && child->get_local_group_root() != root) {
@@ -1532,19 +1534,19 @@
         }
       } else {
 #if !defined(__arm__)
-        __libc_fatal("soinfo for \"%s\"@%p has no version", si->get_soname(), si);
+        __libc_fatal("soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
 #else
-        PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_soname(), si);
+        PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_realpath(), si);
         for_each_dt_needed(si, [&] (const char* library_name) {
           TRACE("deprecated (old format of soinfo): %s needs to unload %s",
-              si->get_soname(), library_name);
+              si->get_realpath(), library_name);
 
           soinfo* needed = find_library(library_name, RTLD_NOLOAD, nullptr);
           if (needed != nullptr) {
             // Not found: for example if symlink was deleted between dlopen and dlclose
             // Since we cannot really handle errors at this point - print and continue.
             PRINT("warning: couldn't find %s needed by %s on unload.",
-                library_name, si->get_soname());
+                library_name, si->get_realpath());
             return;
           } else if (local_unload_list.contains(needed)) {
             // already visited
@@ -1574,7 +1576,8 @@
       soinfo_unload(si);
     }
   } else {
-    TRACE("not unloading '%s' group, decrementing ref_count to %zd", root->get_soname(), ref_count);
+    TRACE("not unloading '%s' group, decrementing ref_count to %zd",
+        root->get_realpath(), ref_count);
   }
 }
 
@@ -1691,7 +1694,7 @@
 
     if (target_si == nullptr) {
       DL_ERR("cannot find \"%s\" from verneed[%zd] in DT_NEEDED list for \"%s\"",
-          target_soname, i, si_from->get_soname());
+          target_soname, i, si_from->get_realpath());
       return false;
     }
 
@@ -1738,7 +1741,7 @@
 
     if (*vi == nullptr) {
       DL_ERR("cannot find verneed/verdef for version index=%d "
-          "referenced by symbol \"%s\" at \"%s\"", sym_ver, sym_name, get_soname());
+          "referenced by symbol \"%s\" at \"%s\"", sym_ver, sym_name, get_realpath());
       return false;
     }
   } else {
@@ -1781,7 +1784,7 @@
     const char* sym_name = nullptr;
     ElfW(Addr) addend = get_addend(rel, reloc);
 
-    DEBUG("Processing '%s' relocation at index %zd", get_soname(), idx);
+    DEBUG("Processing '%s' relocation at index %zd", get_realpath(), idx);
     if (type == R_GENERIC_NONE) {
       continue;
     }
@@ -1805,7 +1808,7 @@
         // We only allow an undefined symbol if this is a weak reference...
         s = &symtab_[sym];
         if (ELF_ST_BIND(s->st_info) != STB_WEAK) {
-          DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, get_soname());
+          DL_ERR("cannot locate symbol \"%s\" referenced by \"%s\"...", sym_name, get_realpath());
           return false;
         }
 
@@ -2001,7 +2004,7 @@
          * R_AARCH64_COPY may only appear in executable objects where e_type is
          * set to ET_EXEC.
          */
-        DL_ERR("%s R_AARCH64_COPY relocations are not supported", get_soname());
+        DL_ERR("%s R_AARCH64_COPY relocations are not supported", get_realpath());
         return false;
       case R_AARCH64_TLS_TPREL64:
         TRACE_TYPE(RELO, "RELO TLS_TPREL64 *** %16llx <- %16llx - %16llx\n",
@@ -2058,7 +2061,7 @@
          * R_ARM_COPY may only appear in executable objects where e_type is
          * set to ET_EXEC.
          */
-        DL_ERR("%s R_ARM_COPY relocations are not supported", get_soname());
+        DL_ERR("%s R_ARM_COPY relocations are not supported", get_realpath());
         return false;
 #elif defined(__i386__)
       case R_386_32:
@@ -2090,7 +2093,7 @@
     return;
   }
 
-  TRACE("[ Calling %s (size %zd) @ %p for '%s' ]", array_name, count, functions, get_soname());
+  TRACE("[ Calling %s (size %zd) @ %p for '%s' ]", array_name, count, functions, get_realpath());
 
   int begin = reverse ? (count - 1) : 0;
   int end = reverse ? -1 : count;
@@ -2101,7 +2104,7 @@
     call_function("function", functions[i]);
   }
 
-  TRACE("[ Done calling %s for '%s' ]", array_name, get_soname());
+  TRACE("[ Done calling %s for '%s' ]", array_name, get_realpath());
 }
 
 void soinfo::call_function(const char* function_name __unused, linker_function_t function) {
@@ -2109,9 +2112,9 @@
     return;
   }
 
-  TRACE("[ Calling %s @ %p for '%s' ]", function_name, function, get_soname());
+  TRACE("[ Calling %s @ %p for '%s' ]", function_name, function, get_realpath());
   function();
-  TRACE("[ Done calling %s @ %p for '%s' ]", function_name, function, get_soname());
+  TRACE("[ Done calling %s @ %p for '%s' ]", function_name, function, get_realpath());
 }
 
 void soinfo::call_pre_init_constructors() {
@@ -2140,14 +2143,14 @@
   if (!is_main_executable() && preinit_array_ != nullptr) {
     // The GNU dynamic linker silently ignores these, but we warn the developer.
     PRINT("\"%s\": ignoring %zd-entry DT_PREINIT_ARRAY in shared library!",
-          get_soname(), preinit_array_count_);
+          get_realpath(), preinit_array_count_);
   }
 
   get_children().for_each([] (soinfo* si) {
     si->call_constructors();
   });
 
-  TRACE("\"%s\": calling constructors", get_soname());
+  TRACE("\"%s\": calling constructors", get_realpath());
 
   // DT_INIT should be called before DT_INIT_ARRAY if both are present.
   call_function("DT_INIT", init_func_);
@@ -2158,7 +2161,7 @@
   if (!constructors_called) {
     return;
   }
-  TRACE("\"%s\": calling destructors", get_soname());
+  TRACE("\"%s\": calling destructors", get_realpath());
 
   // DT_FINI_ARRAY must be parsed in reverse order.
   call_array("DT_FINI_ARRAY", fini_array_, fini_array_count_, true);
@@ -2318,7 +2321,7 @@
 const char* soinfo::get_string(ElfW(Word) index) const {
   if (has_min_version(1) && (index >= strtab_size_)) {
     __libc_fatal("%s: strtab out of bounds error; STRSZ=%zd, name=%d",
-        get_soname(), strtab_size_, index);
+        get_realpath(), strtab_size_, index);
   }
 
   return strtab_ + index;
@@ -2439,7 +2442,7 @@
 
   if (dynamic == nullptr) {
     if (!relocating_linker) {
-      DL_ERR("missing PT_DYNAMIC in \"%s\"", get_soname());
+      DL_ERR("missing PT_DYNAMIC in \"%s\"", get_realpath());
     }
     return false;
   } else {
@@ -2823,15 +2826,15 @@
   }
   if (nbucket_ == 0 && gnu_nbucket_ == 0) {
     DL_ERR("empty/missing DT_HASH/DT_GNU_HASH in \"%s\" "
-        "(new hash type from the future?)", get_soname());
+        "(new hash type from the future?)", get_realpath());
     return false;
   }
   if (strtab_ == 0) {
-    DL_ERR("empty/missing DT_STRTAB in \"%s\"", get_soname());
+    DL_ERR("empty/missing DT_STRTAB in \"%s\"", get_realpath());
     return false;
   }
   if (symtab_ == 0) {
-    DL_ERR("empty/missing DT_SYMTAB in \"%s\"", get_soname());
+    DL_ERR("empty/missing DT_SYMTAB in \"%s\"", get_realpath());
     return false;
   }
   return true;
@@ -2856,10 +2859,10 @@
     // Make segments writable to allow text relocations to work properly. We will later call
     // phdr_table_protect_segments() after all of them are applied and all constructors are run.
     DL_WARN("%s has text relocations. This is wasting memory and prevents "
-            "security hardening. Please fix.", get_soname());
+            "security hardening. Please fix.", get_realpath());
     if (phdr_table_unprotect_segments(phdr, phnum, load_bias) < 0) {
       DL_ERR("can't unprotect loadable segments for \"%s\": %s",
-             get_soname(), strerror(errno));
+             get_realpath(), strerror(errno));
       return false;
     }
   }
@@ -2872,7 +2875,7 @@
         android_relocs_[1] == 'P' &&
         android_relocs_[2] == 'S' &&
         android_relocs_[3] == '2') {
-      DEBUG("[ android relocating %s ]", get_soname());
+      DEBUG("[ android relocating %s ]", get_realpath());
 
       bool relocated = false;
       const uint8_t* packed_relocs = android_relocs_ + 4;
@@ -2895,14 +2898,14 @@
 
 #if defined(USE_RELA)
   if (rela_ != nullptr) {
-    DEBUG("[ relocating %s ]", get_soname());
+    DEBUG("[ relocating %s ]", get_realpath());
     if (!relocate(version_tracker,
             plain_reloc_iterator(rela_, rela_count_), global_group, local_group)) {
       return false;
     }
   }
   if (plt_rela_ != nullptr) {
-    DEBUG("[ relocating %s plt ]", get_soname());
+    DEBUG("[ relocating %s plt ]", get_realpath());
     if (!relocate(version_tracker,
             plain_reloc_iterator(plt_rela_, plt_rela_count_), global_group, local_group)) {
       return false;
@@ -2910,14 +2913,14 @@
   }
 #else
   if (rel_ != nullptr) {
-    DEBUG("[ relocating %s ]", get_soname());
+    DEBUG("[ relocating %s ]", get_realpath());
     if (!relocate(version_tracker,
             plain_reloc_iterator(rel_, rel_count_), global_group, local_group)) {
       return false;
     }
   }
   if (plt_rel_ != nullptr) {
-    DEBUG("[ relocating %s plt ]", get_soname());
+    DEBUG("[ relocating %s plt ]", get_realpath());
     if (!relocate(version_tracker,
             plain_reloc_iterator(plt_rel_, plt_rel_count_), global_group, local_group)) {
       return false;
@@ -2931,14 +2934,14 @@
   }
 #endif
 
-  DEBUG("[ finished linking %s ]", get_soname());
+  DEBUG("[ finished linking %s ]", get_realpath());
 
 #if !defined(__LP64__)
   if (has_text_relocations) {
     // All relocations are done, we can protect our segments back to read-only.
     if (phdr_table_protect_segments(phdr, phnum, load_bias) < 0) {
       DL_ERR("can't protect segments for \"%s\": %s",
-             get_soname(), strerror(errno));
+             get_realpath(), strerror(errno));
       return false;
     }
   }
@@ -2947,7 +2950,7 @@
   /* We can also turn on GNU RELRO protection */
   if (phdr_table_protect_gnu_relro(phdr, phnum, load_bias) < 0) {
     DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
-           get_soname(), strerror(errno));
+           get_realpath(), strerror(errno));
     return false;
   }
 
@@ -2956,14 +2959,14 @@
     if (phdr_table_serialize_gnu_relro(phdr, phnum, load_bias,
                                        extinfo->relro_fd) < 0) {
       DL_ERR("failed serializing GNU RELRO section for \"%s\": %s",
-             get_soname(), strerror(errno));
+             get_realpath(), strerror(errno));
       return false;
     }
   } else if (extinfo && (extinfo->flags & ANDROID_DLEXT_USE_RELRO)) {
     if (phdr_table_map_gnu_relro(phdr, phnum, load_bias,
                                  extinfo->relro_fd) < 0) {
       DL_ERR("failed mapping GNU RELRO section for \"%s\": %s",
-             get_soname(), strerror(errno));
+             get_realpath(), strerror(errno));
       return false;
     }
   }
@@ -3238,7 +3241,7 @@
   fflush(stdout);
 #endif
 
-  TRACE("[ Ready to execute '%s' @ %p ]", si->get_soname(), reinterpret_cast<void*>(si->entry));
+  TRACE("[ Ready to execute '%s' @ %p ]", si->get_realpath(), reinterpret_cast<void*>(si->entry));
   return si->entry;
 }
 
@@ -3254,7 +3257,8 @@
  */
 static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf) {
   ElfW(Addr) offset = elf->e_phoff;
-  const ElfW(Phdr)* phdr_table = reinterpret_cast<const ElfW(Phdr)*>(reinterpret_cast<uintptr_t>(elf) + offset);
+  const ElfW(Phdr)* phdr_table =
+      reinterpret_cast<const ElfW(Phdr)*>(reinterpret_cast<uintptr_t>(elf) + offset);
   const ElfW(Phdr)* phdr_end = phdr_table + elf->e_phnum;
 
   for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_end; phdr++) {
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index cbbcada..201b8a9 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -458,42 +458,6 @@
   ASSERT_EQ(ESRCH, pthread_detach(dead_thread));
 }
 
-TEST(pthread, pthread_detach_no_leak) {
-  size_t initial_bytes = 0;
-  // Run this loop more than once since the first loop causes some memory
-  // to be allocated permenantly. Run an extra loop to help catch any subtle
-  // memory leaks.
-  for (size_t loop = 0; loop < 3; loop++) {
-    // Set the initial bytes on the second loop since the memory in use
-    // should have stabilized.
-    if (loop == 1) {
-      initial_bytes = mallinfo().uordblks;
-    }
-
-    pthread_attr_t attr;
-    ASSERT_EQ(0, pthread_attr_init(&attr));
-    ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
-
-    std::vector<pthread_t> threads;
-    for (size_t i = 0; i < 32; ++i) {
-      pthread_t t;
-      ASSERT_EQ(0, pthread_create(&t, &attr, IdFn, NULL));
-      threads.push_back(t);
-    }
-
-    sleep(1);
-
-    for (size_t i = 0; i < 32; ++i) {
-      ASSERT_EQ(0, pthread_detach(threads[i])) << i;
-    }
-  }
-
-  size_t final_bytes = mallinfo().uordblks;
-  int leaked_bytes = (final_bytes - initial_bytes);
-
-  ASSERT_EQ(0, leaked_bytes);
-}
-
 TEST(pthread, pthread_getcpuclockid__clock_gettime) {
   SpinFunctionHelper spinhelper;
 
diff --git a/tools/bionicbb/presubmit.py b/tools/bionicbb/presubmit.py
index cc6f3cc..3e6ebfa 100644
--- a/tools/bionicbb/presubmit.py
+++ b/tools/bionicbb/presubmit.py
@@ -73,8 +73,10 @@
     build = 'clean-bionic-presubmit'
     if build in jenkins:
         if not dry_run:
-            job = jenkins[build].invoke()
-            url = job.get_build().baseurl
+            _ = jenkins[build].invoke()
+            # https://issues.jenkins-ci.org/browse/JENKINS-27256
+            # url = job.get_build().baseurl
+            url = 'URL UNAVAILABLE'
         else:
             url = 'DRY_RUN_URL'
         logging.info('Cleaning: %s %s', build, url)