Merge "Define char16_t and char32_t to make gcc 5.1 happy"
diff --git a/libc/Android.mk b/libc/Android.mk
index 7a8c344..d41f8af 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -70,7 +70,9 @@
 libc_common_src_files += \
     bionic/__FD_chk.cpp \
     bionic/__fgets_chk.cpp \
+    bionic/__memchr_chk.cpp \
     bionic/__memmove_chk.cpp \
+    bionic/__memrchr_chk.cpp \
     bionic/__poll_chk.cpp \
     bionic/__pread64_chk.cpp \
     bionic/__pread_chk.cpp \
@@ -939,9 +941,6 @@
 LOCAL_CFLAGS := $(libc_common_cflags) \
     -Wframe-larger-than=2048 \
 
-# ssse3-strcmp-slm.S does not compile with Clang.
-LOCAL_CLANG_ASFLAGS_x86_64 += -no-integrated-as
-
 # memcpy.S, memchr.S, etc. do not compile with Clang.
 LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
 LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
@@ -973,9 +972,6 @@
 LOCAL_CFLAGS := $(libc_common_cflags) \
     -Wframe-larger-than=2048 \
 
-# ssse3-strcmp-slm.S does not compile with Clang.
-LOCAL_CLANG_ASFLAGS_x86_64 += -no-integrated-as
-
 # memcpy.S, memchr.S, etc. do not compile with Clang.
 LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
 LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
@@ -1028,9 +1024,6 @@
 LOCAL_CFLAGS := $(libc_common_cflags) \
     -Wframe-larger-than=2048 \
 
-# ssse3-strcmp-slm.S does not compile with Clang.
-LOCAL_CLANG_ASFLAGS_x86_64 += -no-integrated-as
-
 # memcpy.S, memchr.S, etc. do not compile with Clang.
 LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
 LOCAL_CLANG_ASFLAGS_arm64 += -no-integrated-as
@@ -1340,10 +1333,13 @@
 
 LOCAL_C_INCLUDES := $(libc_common_c_includes)
 LOCAL_SRC_FILES := \
+    arch-common/bionic/crtbegin_so.c \
+    arch-common/bionic/crtbrand.S \
     $(libc_arch_dynamic_src_files) \
     bionic/malloc_debug_common.cpp \
     bionic/libc_init_dynamic.cpp \
     bionic/NetdClient.cpp \
+    arch-common/bionic/crtend_so.S \
 
 LOCAL_MODULE := libc
 LOCAL_CLANG := $(use_clang)
@@ -1356,6 +1352,9 @@
 # meaningful name resolution.
 LOCAL_STRIP_MODULE := keep_symbols
 
+# Do not pack libc.so relocations; see http://b/20645321 for details.
+LOCAL_PACK_MODULE_RELOCATIONS := false
+
 # WARNING: The only library libc.so should depend on is libdl.so!  If you add other libraries,
 # make sure to add -Wl,--exclude-libs=libgcc.a to the LOCAL_LDFLAGS for those libraries.  This
 # ensures that symbols that are pulled into those new libraries from libgcc.a are not declared
@@ -1388,15 +1387,15 @@
 
 $(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))
+
+LOCAL_NO_CRT := true
+LOCAL_ASFLAGS += $(libc_crt_target_cflags)
+
 # special for arm
-LOCAL_NO_CRT_arm := true
 LOCAL_CFLAGS_arm += -DCRT_LEGACY_WORKAROUND
-LOCAL_ASFLAGS_arm += $(libc_crt_target_cflags)
 LOCAL_SRC_FILES_arm += \
-    arch-common/bionic/crtbegin_so.c \
-    arch-common/bionic/crtbrand.S \
-    arch-arm/bionic/atexit_legacy.c \
-    arch-common/bionic/crtend_so.S
+    arch-arm/bionic/atexit_legacy.c
+
 LOCAL_ADDRESS_SANITIZER := false
 LOCAL_NATIVE_COVERAGE := $(bionic_coverage)
 
diff --git a/libc/arch-arm/cortex-a9/bionic/memcpy_base.S b/libc/arch-arm/cortex-a9/bionic/memcpy_base.S
index 5e81305..bb08b94 100644
--- a/libc/arch-arm/cortex-a9/bionic/memcpy_base.S
+++ b/libc/arch-arm/cortex-a9/bionic/memcpy_base.S
@@ -44,7 +44,7 @@
         /* check if buffers are aligned. If so, run arm-only version */
         eor         r3, r0, r1
         ands        r3, r3, #0x3
-        beq         __memcpy_base_aligned
+        beq         MEMCPY_BASE_ALIGNED
 
         /* Check the upper size limit for Neon unaligned memory access in memcpy */
         cmp         r2, #224
diff --git a/libc/arch-mips64/bionic/crtbegin.c b/libc/arch-mips64/bionic/crtbegin.c
index 1374fea..bdd423b 100644
--- a/libc/arch-mips64/bionic/crtbegin.c
+++ b/libc/arch-mips64/bionic/crtbegin.c
@@ -92,3 +92,4 @@
 
 #include "../../arch-common/bionic/__dso_handle.h"
 #include "../../arch-common/bionic/atexit.h"
+#include "../../arch-common/bionic/pthread_atfork.h"
diff --git a/libc/arch-x86_64/string/ssse3-strcmp-slm.S b/libc/arch-x86_64/string/ssse3-strcmp-slm.S
index 0dd8c27..e8acd5b 100644
--- a/libc/arch-x86_64/string/ssse3-strcmp-slm.S
+++ b/libc/arch-x86_64/string/ssse3-strcmp-slm.S
@@ -1897,8 +1897,8 @@
 
 	.p2align 4
 L(Byte0):
-	movzx	(%rsi), %ecx
-	movzx	(%rdi), %eax
+	movzbl	(%rsi), %ecx
+	movzbl	(%rdi), %eax
 
 	sub	%ecx, %eax
 	ret
diff --git a/libc/bionic/__memchr_chk.cpp b/libc/bionic/__memchr_chk.cpp
new file mode 100644
index 0000000..d141c04
--- /dev/null
+++ b/libc/bionic/__memchr_chk.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT OWNER 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.
+ */
+
+#undef _FORTIFY_SOURCE
+#include <string.h>
+#include "private/libc_logging.h"
+
+extern "C" void* __memchr_chk(const void* s, int c, size_t n, size_t buf_size) {
+  if (__predict_false(n > buf_size)) {
+    __fortify_chk_fail("memchr: prevented read past end of buffer", 0);
+  }
+
+  return memchr(s, c, n);
+}
diff --git a/libc/bionic/__memrchr_chk.cpp b/libc/bionic/__memrchr_chk.cpp
new file mode 100644
index 0000000..8529dfc
--- /dev/null
+++ b/libc/bionic/__memrchr_chk.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT OWNER 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.
+ */
+
+#undef _FORTIFY_SOURCE
+#include <string.h>
+#include "private/libc_logging.h"
+
+extern "C" void* __memrchr_chk(const void* s, int c, size_t n, size_t buf_size) {
+  if (__predict_false(n > buf_size)) {
+    __fortify_chk_fail("memrchr: prevented read past end of buffer", 0);
+  }
+
+  return memrchr(s, c, n);
+}
diff --git a/libc/bionic/libc_logging.cpp b/libc/bionic/libc_logging.cpp
index 7ad21c4..cb0b334 100644
--- a/libc/bionic/libc_logging.cpp
+++ b/libc/bionic/libc_logging.cpp
@@ -56,6 +56,7 @@
   EVENT_TYPE_LONG     = 1,
   EVENT_TYPE_STRING   = 2,
   EVENT_TYPE_LIST     = 3,
+  EVENT_TYPE_FLOAT    = 4,
 };
 
 struct BufferOutputStream {
diff --git a/libc/bionic/posix_timers.cpp b/libc/bionic/posix_timers.cpp
index bc3aeb2..c8f71c8 100644
--- a/libc/bionic/posix_timers.cpp
+++ b/libc/bionic/posix_timers.cpp
@@ -174,10 +174,10 @@
     return -1;
   }
 
-  // Give the thread a meaningful name.
+  // Give the thread a specific meaningful name.
   // It can't do this itself because the kernel timer isn't created until after it's running.
-  char name[32];
-  snprintf(name, sizeof(name), "POSIX interval timer %d", to_kernel_timer_id(timer));
+  char name[16]; // 16 is the kernel-imposed limit.
+  snprintf(name, sizeof(name), "POSIX timer %d", to_kernel_timer_id(timer));
   pthread_setname_np(timer->callback_thread, name);
 
   *timer_id = timer;
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
index aae99b1..c436a16 100644
--- a/libc/bionic/system_properties.cpp
+++ b/libc/bionic/system_properties.cpp
@@ -598,6 +598,16 @@
     return map_prop_area_rw();
 }
 
+unsigned int __system_property_area_serial()
+{
+    prop_area *pa = __system_property_area__;
+    if (!pa) {
+        return -1;
+    }
+    // Make sure this read fulfilled before __system_property_serial
+    return atomic_load_explicit(&(pa->serial), memory_order_acquire);
+}
+
 const prop_info *__system_property_find(const char *name)
 {
     if (__predict_false(compat_mode)) {
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 84bf56d..efca577 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -176,6 +176,27 @@
 #include <android/legacy_stdlib_inlines.h>
 #endif
 
+#if defined(__BIONIC_FORTIFY)
+
+extern char* __realpath_real(const char*, char*) __RENAME(realpath);
+__errordecl(__realpath_size_error, "realpath output parameter must be NULL or a >= PATH_MAX bytes buffer");
+
+#if !defined(__clang__)
+__BIONIC_FORTIFY_INLINE
+char* realpath(const char* path, char* resolved) {
+    size_t bos = __bos(resolved);
+
+    /* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */
+    if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < 4096) {
+        __realpath_size_error();
+    }
+
+    return __realpath_real(path, resolved);
+}
+#endif
+
+#endif /* defined(__BIONIC_FORTIFY) */
+
 __END_DECLS
 
 #endif /* _STDLIB_H */
diff --git a/libc/include/string.h b/libc/include/string.h
index fffe136..d32c164 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -121,6 +121,13 @@
 #define __bionic_using_gnu_basename
 #endif
 
+extern void* __memchr_chk(const void*, int, size_t, size_t);
+__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
+
+extern void* __memrchr_chk(const void*, int, size_t, size_t);
+__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
+extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
+
 extern char* __stpncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t);
 extern char* __strncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t);
 extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t) __RENAME(strlcpy);
@@ -131,6 +138,48 @@
 #if defined(__BIONIC_FORTIFY)
 
 __BIONIC_FORTIFY_INLINE
+void* memchr(const void *s, int c, size_t n) {
+    size_t bos = __bos(s);
+
+#if !defined(__clang__)
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __builtin_memchr(s, c, n);
+    }
+
+    if (__builtin_constant_p(n) && (n > bos)) {
+        __memchr_buf_size_error();
+    }
+
+    if (__builtin_constant_p(n) && (n <= bos)) {
+        return __builtin_memchr(s, c, n);
+    }
+#endif
+
+    return __memchr_chk(s, c, n, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+void* memrchr(const void *s, int c, size_t n) {
+    size_t bos = __bos(s);
+
+#if !defined(__clang__)
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __memrchr_real(s, c, n);
+    }
+
+    if (__builtin_constant_p(n) && (n > bos)) {
+        __memrchr_buf_size_error();
+    }
+
+    if (__builtin_constant_p(n) && (n <= bos)) {
+        return __memrchr_real(s, c, n);
+    }
+#endif
+
+    return __memrchr_chk(s, c, n, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
 void* memcpy(void* __restrict dest, const void* __restrict src, size_t copy_amount) {
     return __builtin___memcpy_chk(dest, src, copy_amount, __bos0(dest));
 }
diff --git a/libc/include/sys/_system_properties.h b/libc/include/sys/_system_properties.h
index 7ff3ded..c200295 100644
--- a/libc/include/sys/_system_properties.h
+++ b/libc/include/sys/_system_properties.h
@@ -98,6 +98,24 @@
 */
 int __system_property_area_init();
 
+/* Read the global serial number of the system properties
+**
+** Called to predict if a series of cached __system_property_find
+** objects will have seen __system_property_serial values change.
+** But also aids the converse, as changes in the global serial can
+** also be used to predict if a failed __system_property_find
+** could in-turn now find an new object; thus preventing the
+** cycles of effort to poll __system_property_find.
+**
+** Called at the beginning of a cache cycle to signal _any_ possible
+** changes have occurred since last. If there is, check each individual
+** __system_property_serial to confirm dirty, or __system_property_find
+** to check if the property now exists.
+**
+** Returns the serial number on success, -1 on error.
+*/
+unsigned int __system_property_area_serial();
+
 /* Add a new system property.  Can only be done by a single
 ** process that has write access to the property area, and
 ** that process must handle sequencing to ensure the property
diff --git a/libc/zoneinfo/tzdata b/libc/zoneinfo/tzdata
index 3661b68..2c734fa 100644
--- a/libc/zoneinfo/tzdata
+++ b/libc/zoneinfo/tzdata
Binary files differ
diff --git a/linker/linker.cpp b/linker/linker.cpp
index be7b10c..ceee3a5 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -61,21 +61,6 @@
 #include "linker_reloc_iterators.h"
 #include "ziparchive/zip_archive.h"
 
-/* >>> IMPORTANT NOTE - READ ME BEFORE MODIFYING <<<
- *
- * Do NOT use malloc() and friends or pthread_*() code here.
- * Don't use printf() either; it's caused mysterious memory
- * corruption in the past.
- * The linker runs before we bring up libc and it's easiest
- * to make sure it does not depend on any complex libc features
- *
- * open issues / todo:
- *
- * - cleaner error reporting
- * - after linking, set as much stuff as possible to READONLY
- *   and NOEXEC
- */
-
 // Override macros to use C++ style casts
 #undef ELF_ST_TYPE
 #define ELF_ST_TYPE(x) (static_cast<uint32_t>(x) & 0xf)
@@ -2444,7 +2429,7 @@
   /* We can't log anything until the linker is relocated */
   bool relocating_linker = (flags_ & FLAG_LINKER) != 0;
   if (!relocating_linker) {
-    INFO("[ linking %s ]", get_soname());
+    INFO("[ linking %s ]", get_realpath());
     DEBUG("si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags_);
   }
 
@@ -3037,6 +3022,8 @@
   insert_soinfo_into_debug_map(linker_soinfo_for_gdb);
 }
 
+extern "C" int __system_properties_init(void);
+
 /*
  * This code is called after the linker has linked itself and
  * fixed it's own GOT. It is safe to make references to externs
@@ -3051,6 +3038,9 @@
   // Initialize environment functions, and get to the ELF aux vectors table.
   linker_env_init(args);
 
+  // Initialize system properties
+  __system_properties_init(); // may use 'environ'
+
   // If this is a setuid/setgid program, close the security hole described in
   // ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
   if (get_AT_SECURE()) {
@@ -3150,6 +3140,7 @@
   for (const auto& ld_preload_name : g_ld_preload_names) {
     needed_library_name_list.push_back(ld_preload_name.c_str());
     ++needed_libraries_count;
+    ++ld_preloads_count;
   }
 
   for_each_dt_needed(si, [&](const char* name) {
diff --git a/linker/linker_environ.cpp b/linker/linker_environ.cpp
index 9a0f009..3c466a2 100644
--- a/linker/linker_environ.cpp
+++ b/linker/linker_environ.cpp
@@ -36,7 +36,6 @@
 
 #include "private/KernelArgumentBlock.h"
 
-static char** _envp;
 static bool _AT_SECURE_value = true;
 
 bool get_AT_SECURE() {
@@ -150,8 +149,8 @@
 }
 
 static void __sanitize_environment_variables() {
-  char** src  = _envp;
-  char** dst = _envp;
+  char** src  = environ;
+  char** dst = environ;
   for (; src[0] != nullptr; ++src) {
     if (!__is_valid_environment_variable(src[0])) {
       continue;
@@ -168,7 +167,7 @@
 
 void linker_env_init(KernelArgumentBlock& args) {
   // Store environment pointer - can't be null.
-  _envp = args.envp;
+  environ = args.envp;
 
   __init_AT_SECURE(args);
   __sanitize_environment_variables();
@@ -179,7 +178,7 @@
     return nullptr;
   }
 
-  for (char** p = _envp; p[0] != nullptr; ++p) {
+  for (char** p = environ; p[0] != nullptr; ++p) {
     const char* val = env_match(p[0], name);
     if (val != nullptr) {
       if (val[0] == '\0') {
diff --git a/linker/linker_mips.cpp b/linker/linker_mips.cpp
index 0769f82..87b811f 100644
--- a/linker/linker_mips.cpp
+++ b/linker/linker_mips.cpp
@@ -128,7 +128,7 @@
         if (s != nullptr) {
           *reinterpret_cast<ElfW(Addr)*>(reloc) += sym_addr;
         } else {
-          *reinterpret_cast<ElfW(Addr)*>(reloc) += base;
+          *reinterpret_cast<ElfW(Addr)*>(reloc) += load_bias;
         }
         break;
       default:
diff --git a/tests/Android.mk b/tests/Android.mk
index c942375..cd65c10 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -295,9 +295,7 @@
 # which bionic does not support. Reenable this once this question is resolved.
 bionic-unit-tests_clang_target := false
 
-ifneq ($(filter $(TARGET_ARCH),arm arm64),$(TARGET_ARCH))
 bionic-unit-tests_shared_libraries_target += libdl_test_df_1_global
-endif
 
 module := bionic-unit-tests
 module_tag := optional
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 1023644..6b1f109 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -626,7 +626,6 @@
 }
 
 TEST(dlfcn, dlsym_df_1_global) {
-#if !defined(__arm__) && !defined(__aarch64__)
   void* handle = dlopen("libtest_dlsym_df_1_global.so", RTLD_NOW);
   ASSERT_TRUE(handle != nullptr) << dlerror();
   int (*get_answer)();
@@ -634,9 +633,6 @@
   ASSERT_TRUE(get_answer != nullptr) << dlerror();
   ASSERT_EQ(42, get_answer());
   ASSERT_EQ(0, dlclose(handle));
-#else
-  GTEST_LOG_(INFO) << "This test does nothing on arm/arm64 (to be reenabled once b/18137520 or b/18130452 are fixed).\n";
-#endif
 }
 
 TEST(dlfcn, dlopen_failure) {
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index c78661e..c432c2e 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -354,17 +354,17 @@
 # Library with DF_1_GLOBAL
 # -----------------------------------------------------------------------------
 libdl_test_df_1_global_src_files := dl_df_1_global.cpp
-libdl_test_df_1_global_ldflags := -fuse-ld=bfd -Wl,-z,global
-module := libdl_test_df_1_global
-# TODO: re-enable arm once b/18137520 or b/18130452 are fixed
-ifeq ($(filter $(TARGET_ARCH),arm arm64),)
-include $(LOCAL_PATH)/Android.build.testlib.mk
-else
-# build it for host only
-build_target := SHARED_LIBRARY
-build_type := host
-include $(TEST_PATH)/Android.build.mk
+libdl_test_df_1_global_ldflags := -Wl,-z,global
+# TODO (dimitry): x86* toolchain does not support -z global - switch to bfd
+ifeq ($(filter $(TARGET_ARCH),x86 x86_64),$(TARGET_ARCH))
+libdl_test_df_1_global_ldflags_target := -fuse-ld=bfd
 endif
+# TODO (dimitry): host ld.gold does not yet support -z global
+# remove this line once it is updated.
+libdl_test_df_1_global_ldflags_host := -fuse-ld=bfd
+
+module := libdl_test_df_1_global
+include $(LOCAL_PATH)/Android.build.testlib.mk
 
 # -----------------------------------------------------------------------------
 # Library using symbol from libdl_test_df_1_global
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index b8cfd56..cb5e818 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -404,7 +404,9 @@
 }
 
 TEST(pthread, pthread_setname_np__too_long) {
-  ASSERT_EQ(ERANGE, pthread_setname_np(pthread_self(), "this name is far too long for linux"));
+  // The limit is 15 characters --- the kernel's buffer is 16, but includes a NUL.
+  ASSERT_EQ(0, pthread_setname_np(pthread_self(), "123456789012345"));
+  ASSERT_EQ(ERANGE, pthread_setname_np(pthread_self(), "1234567890123456"));
 }
 
 TEST(pthread, pthread_setname_np__self) {
diff --git a/tools/relocation_packer/src/elf_file.cc b/tools/relocation_packer/src/elf_file.cc
index fb74233..d06bd63 100644
--- a/tools/relocation_packer/src/elf_file.cc
+++ b/tools/relocation_packer/src/elf_file.cc
@@ -37,11 +37,13 @@
 static constexpr uint32_t SHT_ANDROID_REL = SHT_LOOS + 1;
 static constexpr uint32_t SHT_ANDROID_RELA = SHT_LOOS + 2;
 
+static const size_t kPageSize = 4096;
+
 // Alignment to preserve, in bytes.  This must be at least as large as the
 // largest d_align and sh_addralign values found in the loaded file.
 // Out of caution for RELRO page alignment, we preserve to a complete target
 // page.  See http://www.airs.com/blog/archives/189.
-static constexpr size_t kPreserveAlignment = 4096;
+static const size_t kPreserveAlignment = kPageSize;
 
 // Get section data.  Checks that the section has exactly one data entry,
 // so that the section size and the data size are the same.  True in
@@ -318,9 +320,13 @@
     } else {
       program_header->p_vaddr -= hole_size;
       program_header->p_paddr -= hole_size;
+      if (program_header->p_align > kPageSize) {
+        program_header->p_align = kPageSize;
+      }
       VLOG(1) << "phdr[" << i
               << "] p_vaddr adjusted to "<< program_header->p_vaddr
-              << "; p_paddr adjusted to "<< program_header->p_paddr;
+              << "; p_paddr adjusted to "<< program_header->p_paddr
+              << "; p_align adjusted to "<< program_header->p_align;
     }
   }
 }
@@ -466,6 +472,16 @@
               << " d_val adjusted to " << dynamic->d_un.d_val;
     }
 
+    // Special case: DT_MIPS_RLD_MAP2 stores the difference between dynamic
+    // entry address and the address of the _r_debug (used by GDB)
+    // since the dynamic section and target address are on the
+    // different sides of the hole it needs to be adjusted accordingly
+    if (tag == DT_MIPS_RLD_MAP2) {
+      dynamic->d_un.d_val += hole_size;
+      VLOG(1) << "dynamic[" << i << "] " << dynamic->d_tag
+              << " d_val adjusted to " << dynamic->d_un.d_val;
+    }
+
     // Ignore DT_RELCOUNT and DT_RELACOUNT: (1) nobody uses them and
     // technically (2) the relative relocation count is not changed.
 
@@ -618,8 +634,8 @@
   typedef typename ELF::Rela Rela;
 
   if (has_android_relocations_) {
-    LOG(ERROR) << "Relocation table is already packed";
-    return false;
+    LOG(INFO) << "Relocation table is already packed";
+    return true;
   }
 
   // If no relocations then we have nothing packable.  Perhaps
diff --git a/tools/relocation_packer/src/elf_file_unittest.cc b/tools/relocation_packer/src/elf_file_unittest.cc
index 5271eef..32f7968 100644
--- a/tools/relocation_packer/src/elf_file_unittest.cc
+++ b/tools/relocation_packer/src/elf_file_unittest.cc
@@ -103,8 +103,8 @@
 static void ProcessUnpack(FILE* relocs_so, FILE* packed_relocs_so) {
   relocation_packer::ElfFile<ELF> elf_file(fileno(packed_relocs_so));
 
-  // Ensure packing fails (already packed).
-  EXPECT_FALSE(elf_file.PackRelocations());
+  // Ensure packing already packed elf-file does not fail the build.
+  EXPECT_TRUE(elf_file.PackRelocations());
 
   // Unpack golden relocations, and check files are now identical.
   EXPECT_TRUE(elf_file.UnpackRelocations());
diff --git a/tools/relocation_packer/src/elf_traits.h b/tools/relocation_packer/src/elf_traits.h
index 41b06c8..1c938fa 100644
--- a/tools/relocation_packer/src/elf_traits.h
+++ b/tools/relocation_packer/src/elf_traits.h
@@ -10,6 +10,10 @@
 #include "elf.h"
 #include "libelf.h"
 
+#if !defined(DT_MIPS_RLD_MAP2)
+#define DT_MIPS_RLD_MAP2 0x70000035
+#endif
+
 // ELF is a traits structure used to provide convenient aliases for
 // 32/64 bit Elf types and functions, depending on the target file.
 
diff --git a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so
index a2b0039..ed85ce1 100755
--- a/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so
+++ b/tools/relocation_packer/test_data/elf_file_unittest_relocs_arm64_packed.so
Binary files differ