Merge "Revert "Revert "Enable linker -fix-cortex-a53-843419"""
diff --git a/core/Makefile b/core/Makefile
index 8811b9a..f0b1d56 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1271,7 +1271,10 @@
 
 # Shared libraries.
 DISTTOOLS += \
-  $(HOST_LIBRARY_PATH)/libc++$(HOST_SHLIB_SUFFIX)
+  $(HOST_LIBRARY_PATH)/libc++$(HOST_SHLIB_SUFFIX) \
+  $(HOST_LIBRARY_PATH)/liblog$(HOST_SHLIB_SUFFIX) \
+  $(HOST_LIBRARY_PATH)/libcutils$(HOST_SHLIB_SUFFIX) \
+  $(HOST_LIBRARY_PATH)/libselinux$(HOST_SHLIB_SUFFIX)
 
 OTATOOLS := $(DISTTOOLS) \
   $(HOST_OUT_EXECUTABLES)/aapt
diff --git a/core/base_rules.mk b/core/base_rules.mk
index 38f04f1..0294cf2 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -87,6 +87,7 @@
 # file, tag the module as "gnu".  Search for "*_GPL*", "*_LGPL*" and "*_MPL*"
 # so that we can also find files like MODULE_LICENSE_GPL_AND_AFL
 #
+license_files := $(call find-parent-file,$(LOCAL_PATH),MODULE_LICENSE*)
 gpl_license_file := $(call find-parent-file,$(LOCAL_PATH),MODULE_LICENSE*_GPL* MODULE_LICENSE*_MPL* MODULE_LICENSE*_LGPL*)
 ifneq ($(gpl_license_file),)
   my_module_tags += gnu
@@ -643,6 +644,21 @@
 
 INSTALLABLE_FILES.$(LOCAL_INSTALLED_MODULE).MODULE := $(my_register_name)
 
+##########################################################
+# Track module-level dependencies.
+# Use $(LOCAL_MODULE) instead of $(my_register_name) to ignore module's bitness.
+ALL_DEPS.MODULES := $(sort $(ALL_DEPS.MODULES) $(LOCAL_MODULE))
+ALL_DEPS.$(LOCAL_MODULE).ALL_DEPS := $(sort \
+  $(ALL_MODULES.$(LOCAL_MODULE).ALL_DEPS) \
+  $(LOCAL_STATIC_LIBRARIES) \
+  $(LOCAL_WHOLE_STATIC_LIBRARIES) \
+  $(LOCAL_SHARED_LIBRARIES) \
+  $(LOCAL_STATIC_JAVA_LIBRARIES) \
+  $(LOCAL_JAVA_LIBRARIES)\
+  $(LOCAL_JNI_SHARED_LIBRARIES))
+
+ALL_DEPS.$(LOCAL_MODULE).LICENSE := $(sort $(ALL_DEPS.$(LOCAL_MODULE).LICENSE) $(license_files))
+
 ###########################################################
 ## Take care of my_module_tags
 ###########################################################
diff --git a/core/binary.mk b/core/binary.mk
index 69131c3..d3d050e 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -77,10 +77,12 @@
     my_ndk_sysroot_lib := $(my_ndk_sysroot)/usr/lib
   endif
 
-  # The bionic linker now has support for gnu style hashes (which are much
-  # faster!), but shipping to older devices requires the old style hash.
+  # The bionic linker now has support for packed relocations and gnu style
+  # hashes (which are much faster!), but shipping to older devices requires
+  # the old style hash and disabling packed relocations.
   #ifeq ($(shell expr $(LOCAL_SDK_VERSION) >= FIRST_SUPPORTED_VERSION),0)
     my_ldflags += -Wl,--hash-style=sysv
+    LOCAL_PACK_MODULE_RELOCATIONS := false
   #endif
 
   # Set up the NDK stl variant. Starting from NDK-r5 the c++ stl resides in a separate location.
@@ -204,7 +206,7 @@
 endif
 
 # Add in libcompiler_rt for all regular device builds
-ifeq (,$(LOCAL_SDK_VERSION)$(LOCAL_IS_HOST_MODULE)$(WITHOUT_LIBCOMPILER_RT))
+ifeq (,$(LOCAL_SDK_VERSION)$(WITHOUT_LIBCOMPILER_RT))
   my_static_libraries += $(COMPILER_RT_CONFIG_EXTRA_STATIC_LIBRARIES)
 endif
 
diff --git a/core/clang/TARGET_arm.mk b/core/clang/TARGET_arm.mk
index 6f6d624..62ce242 100644
--- a/core/clang/TARGET_arm.mk
+++ b/core/clang/TARGET_arm.mk
@@ -66,3 +66,7 @@
 $(clang_2nd_arch_prefix)RS_COMPAT_TRIPLE := armv7-none-linux-gnueabi
 
 $(clang_2nd_arch_prefix)TARGET_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-arm-android.a
+
+# Address sanitizer clang config
+$(clang_2nd_arch_prefix)ADDRESS_SANITIZER_RUNTIME_LIBRARY := libclang_rt.asan-arm-android
+$(clang_2nd_arch_prefix)ADDRESS_SANITIZER_RPATH := /system/lib/asan
diff --git a/core/clang/TARGET_arm64.mk b/core/clang/TARGET_arm64.mk
index b67d458..ea4d937 100644
--- a/core/clang/TARGET_arm64.mk
+++ b/core/clang/TARGET_arm64.mk
@@ -64,3 +64,7 @@
 RS_COMPAT_TRIPLE := aarch64-linux-android
 
 TARGET_LIBPROFILE_RT := $(LLVM_RTLIB_PATH)/libclang_rt.profile-aarch64-android.a
+
+# Address sanitizer clang config
+ADDRESS_SANITIZER_RUNTIME_LIBRARY := libclang_rt.asan-arm64-android
+ADDRESS_SANITIZER_RPATH := /system/lib64/asan
diff --git a/core/clang/config.mk b/core/clang/config.mk
index 13a5ba1..512b116 100644
--- a/core/clang/config.mk
+++ b/core/clang/config.mk
@@ -49,6 +49,11 @@
 CLANG_CONFIG_EXTRA_CFLAGS += \
   -Wno-reserved-id-macro
 
+# Disable overly aggressive warning for format strings.
+# Bug: 20148343
+CLANG_CONFIG_EXTRA_CFLAGS += \
+  -Wno-format-pedantic
+
 # Workaround for ccache with clang.
 # See http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html.
 CLANG_CONFIG_EXTRA_CFLAGS += \
@@ -63,10 +68,13 @@
   -finline-functions \
   -finline-limit=64 \
   -fno-canonical-system-headers \
+  -Wno-clobbered \
+  -fno-devirtualize \
   -fno-tree-sra \
   -fprefetch-loop-arrays \
   -funswitch-loops \
   -Wmaybe-uninitialized \
+  -Wno-error=clobbered \
   -Wno-error=maybe-uninitialized \
   -Wno-error=unused-but-set-parameter \
   -Wno-error=unused-but-set-variable \
@@ -93,6 +101,32 @@
 CLANG_CONFIG_TARGET_EXTRA_CPPFLAGS := -nostdlibinc
 CLANG_CONFIG_TARGET_EXTRA_LDFLAGS :=
 
+CLANG_DEFAULT_UB_CHECKS := \
+  bool \
+  integer-divide-by-zero \
+  return \
+  returns-nonnull-attribute \
+  shift-exponent \
+  unreachable \
+  vla-bound \
+
+# TODO(danalbert): The following checks currently have compiler performance
+# issues.
+# CLANG_DEFAULT_UB_CHECKS += alignment
+# CLANG_DEFAULT_UB_CHECKS += bounds
+# CLANG_DEFAULT_UB_CHECKS += enum
+# CLANG_DEFAULT_UB_CHECKS += float-cast-overflow
+# CLANG_DEFAULT_UB_CHECKS += float-divide-by-zero
+# CLANG_DEFAULT_UB_CHECKS += nonnull-attribute
+# CLANG_DEFAULT_UB_CHECKS += null
+# CLANG_DEFAULT_UB_CHECKS += shift-base
+# CLANG_DEFAULT_UB_CHECKS += signed-integer-overflow
+
+# TODO(danalbert): Fix UB in libc++'s __tree so we can turn this on.
+# https://llvm.org/PR19302
+# http://reviews.llvm.org/D6974
+# CLANG_DEFAULT_UB_CHECKS += object-size
+
 # HOST config
 clang_2nd_arch_prefix :=
 include $(BUILD_SYSTEM)/clang/HOST_$(HOST_ARCH).mk
@@ -113,12 +147,10 @@
 include $(BUILD_SYSTEM)/clang/TARGET_$(TARGET_2ND_ARCH).mk
 endif
 
-# Address sanitizer clang config
-ADDRESS_SANITIZER_RUNTIME_LIBRARY := libclang_rt.asan_$(TARGET_ARCH)_android
-ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS := -fsanitize=address -fno-omit-frame-pointer
+ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS := -fno-omit-frame-pointer
 ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS := -Wl,-u,__asan_preinit
 
-ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES := libdl $(ADDRESS_SANITIZER_RUNTIME_LIBRARY)
+ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES := libdl
 ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES := libasan
 
 # This allows us to use the superset of functionality that compiler-rt
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 7837ae3..1357b39 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -92,11 +92,10 @@
 LOCAL_COPY_HEADERS:=
 LOCAL_FORCE_STATIC_EXECUTABLE:=
 LOCAL_ADDITIONAL_DEPENDENCIES:=
-LOCAL_COMPRESS_MODULE_SYMBOLS:=
 LOCAL_STRIP_MODULE:=
+LOCAL_PACK_MODULE_RELOCATIONS:=
 LOCAL_JNI_SHARED_LIBRARIES:=
 LOCAL_JNI_SHARED_LIBRARIES_ABI:=
-LOCAL_JNI_SHARED_LIBRARIES_ZIP_OPTIONS:=
 LOCAL_PREBUILT_JNI_LIBS:=
 LOCAL_JAR_MANIFEST:=
 LOCAL_INSTRUMENTATION_FOR:=
@@ -173,6 +172,8 @@
 LOCAL_NATIVE_COVERAGE :=
 LOCAL_DPI_VARIANTS:=
 LOCAL_DPI_FILE_STEM:=
+LOCAL_SANITIZE:=
+LOCAL_SANITIZE_RECOVER:=
 
 # arch specific variables
 LOCAL_SRC_FILES_$(TARGET_ARCH):=
diff --git a/core/combo/HOST_darwin-x86.mk b/core/combo/HOST_darwin-x86.mk
index 7fa48ff..8389bb8 100644
--- a/core/combo/HOST_darwin-x86.mk
+++ b/core/combo/HOST_darwin-x86.mk
@@ -56,12 +56,6 @@
 $(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += \
     -include $(call select-android-config-h,darwin-x86)
 
-ifneq ($(filter 10.7 10.7.% 10.8 10.8.%, $(build_mac_version)),)
-       $(combo_2nd_arch_prefix)HOST_RUN_RANLIB_AFTER_COPYING := false
-else
-       $(combo_2nd_arch_prefix)HOST_RUN_RANLIB_AFTER_COPYING := true
-       PRE_LION_DYNAMIC_LINKER_OPTIONS := -Wl,-dynamic
-endif
 $(combo_2nd_arch_prefix)HOST_GLOBAL_ARFLAGS := cqs
 
 ############################################################
@@ -91,7 +85,7 @@
 $(hide) $(PRIVATE_CXX) \
         -Wl,-rpath,@loader_path/../$(notdir $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES)) \
         -o $@ \
-        $(PRE_LION_DYNAMIC_LINKER_OPTIONS) -Wl,-headerpad_max_install_names \
+        -Wl,-headerpad_max_install_names \
         $($(PRIVATE_2ND_ARCH_VAR_PREFIX)HOST_GLOBAL_LD_DIRS) \
         $(if $(PRIVATE_NO_DEFAULT_COMPILER_FLAGS),, \
            $(PRIVATE_HOST_GLOBAL_LDFLAGS) \
diff --git a/core/combo/HOST_darwin-x86_64.mk b/core/combo/HOST_darwin-x86_64.mk
index c06933d..0efa78f 100644
--- a/core/combo/HOST_darwin-x86_64.mk
+++ b/core/combo/HOST_darwin-x86_64.mk
@@ -55,11 +55,6 @@
 HOST_GLOBAL_CFLAGS += \
     -include $(call select-android-config-h,darwin-x86)
 
-ifneq ($(filter 10.7 10.7.% 10.8 10.8.%, $(build_mac_version)),)
-       HOST_RUN_RANLIB_AFTER_COPYING := false
-else
-       HOST_RUN_RANLIB_AFTER_COPYING := true
-endif
 HOST_GLOBAL_ARFLAGS := cqs
 
 # We Reuse the following functions with the same name from HOST_darwin-x86.mk:
diff --git a/core/combo/HOST_linux-x86.mk b/core/combo/HOST_linux-x86.mk
index 5f62400..8eda6c0 100644
--- a/core/combo/HOST_linux-x86.mk
+++ b/core/combo/HOST_linux-x86.mk
@@ -29,7 +29,7 @@
 
 # We expect SSE3 floating point math.
 $(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -msse3 -mfpmath=sse -m32 -Wa,--noexecstack -march=prescott
-$(combo_2nd_arch_prefix)HOST_GLOBAL_LDFLAGS += -m32 -Wl,-z,noexecstack
+$(combo_2nd_arch_prefix)HOST_GLOBAL_LDFLAGS += -m32 -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now
 
 ifneq ($(strip $(BUILD_HOST_static)),)
 # Statically-linked binaries are desirable for sandboxed environment
@@ -40,8 +40,8 @@
   -no-canonical-prefixes \
   -include $(call select-android-config-h,linux-x86)
 
-# Disable new longjmp in glibc 2.11 and later. See bug 2967937. Same for 2.15?
-$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0
+# TODO: Set _FORTIFY_SOURCE=2. Bug 20558757.
+$(combo_2nd_arch_prefix)HOST_GLOBAL_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -fstack-protector
 
 # Workaround differences in inttypes.h between host and target.
 # See bug 12708004.
diff --git a/core/combo/HOST_linux-x86_64.mk b/core/combo/HOST_linux-x86_64.mk
index 3685712..e268e41 100644
--- a/core/combo/HOST_linux-x86_64.mk
+++ b/core/combo/HOST_linux-x86_64.mk
@@ -28,7 +28,7 @@
 HOST_TOOLCHAIN_FOR_CLANG := prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/
 
 HOST_GLOBAL_CFLAGS += -m64 -Wa,--noexecstack
-HOST_GLOBAL_LDFLAGS += -m64 -Wl,-z,noexecstack
+HOST_GLOBAL_LDFLAGS += -m64 -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now
 
 ifneq ($(strip $(BUILD_HOST_static)),)
 # Statically-linked binaries are desirable for sandboxed environment
@@ -40,8 +40,8 @@
   -no-canonical-prefixes \
   -include $(call select-android-config-h,linux-x86)
 
-# Disable new longjmp in glibc 2.11 and later. See bug 2967937. Same for 2.15?
-HOST_GLOBAL_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0
+# TODO: Set _FORTIFY_SOURCE=2. Bug 20558757.
+HOST_GLOBAL_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -fstack-protector
 
 # Workaround differences in inttypes.h between host and target.
 # See bug 12708004.
diff --git a/core/combo/TARGET_linux-arm.mk b/core/combo/TARGET_linux-arm.mk
index 8059b2a..a2d3dee 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -57,13 +57,13 @@
 $(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX := $($(combo_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT)/bin/arm-linux-androideabi-
 endif
 
-$(combo_2nd_arch_prefix)TARGET_CC := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_CXX := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)g++$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_AR := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_OBJCOPY := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_LD := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_READELF := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)readelf$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_STRIP := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)strip$(HOST_EXECUTABLE_SUFFIX)
+$(combo_2nd_arch_prefix)TARGET_CC := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)gcc
+$(combo_2nd_arch_prefix)TARGET_CXX := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)g++
+$(combo_2nd_arch_prefix)TARGET_AR := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ar
+$(combo_2nd_arch_prefix)TARGET_OBJCOPY := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)objcopy
+$(combo_2nd_arch_prefix)TARGET_LD := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ld
+$(combo_2nd_arch_prefix)TARGET_READELF := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)readelf
+$(combo_2nd_arch_prefix)TARGET_STRIP := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)strip
 
 $(combo_2nd_arch_prefix)TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
 
@@ -188,7 +188,7 @@
 $(combo_2nd_arch_prefix)TARGET_CRTBEGIN_SO_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
 $(combo_2nd_arch_prefix)TARGET_CRTEND_SO_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
 
-$(combo_2nd_arch_prefix)TARGET_STRIP_MODULE:=true
+$(combo_2nd_arch_prefix)TARGET_PACK_MODULE_RELOCATIONS := true
 
 $(combo_2nd_arch_prefix)TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libm
 
diff --git a/core/combo/TARGET_linux-arm64.mk b/core/combo/TARGET_linux-arm64.mk
index c66b099..0e4c6f1 100644
--- a/core/combo/TARGET_linux-arm64.mk
+++ b/core/combo/TARGET_linux-arm64.mk
@@ -57,13 +57,13 @@
 TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/aarch64-linux-android-
 endif
 
-TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
-TARGET_CXX := $(TARGET_TOOLS_PREFIX)g++$(HOST_EXECUTABLE_SUFFIX)
-TARGET_AR := $(TARGET_TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
-TARGET_OBJCOPY := $(TARGET_TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
-TARGET_LD := $(TARGET_TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
-TARGET_READELF := $(TARGET_TOOLS_PREFIX)readelf$(HOST_EXECUTABLE_SUFFIX)
-TARGET_STRIP := $(TARGET_TOOLS_PREFIX)strip$(HOST_EXECUTABLE_SUFFIX)
+TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc
+TARGET_CXX := $(TARGET_TOOLS_PREFIX)g++
+TARGET_AR := $(TARGET_TOOLS_PREFIX)ar
+TARGET_OBJCOPY := $(TARGET_TOOLS_PREFIX)objcopy
+TARGET_LD := $(TARGET_TOOLS_PREFIX)ld
+TARGET_READELF := $(TARGET_TOOLS_PREFIX)readelf
+TARGET_STRIP := $(TARGET_TOOLS_PREFIX)strip
 
 TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
 
@@ -159,7 +159,7 @@
 TARGET_CRTBEGIN_SO_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
 TARGET_CRTEND_SO_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
 
-TARGET_STRIP_MODULE:=true
+TARGET_PACK_MODULE_RELOCATIONS := true
 
 TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libm
 
diff --git a/core/combo/TARGET_linux-mips.mk b/core/combo/TARGET_linux-mips.mk
index 55566eb..962aa45 100644
--- a/core/combo/TARGET_linux-mips.mk
+++ b/core/combo/TARGET_linux-mips.mk
@@ -57,13 +57,13 @@
 $(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX := $($(combo_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT)/bin/mips64el-linux-android-
 endif
 
-$(combo_2nd_arch_prefix)TARGET_CC := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_CXX := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)g++$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_AR := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_OBJCOPY := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_LD := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_READELF := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)readelf$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_STRIP := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)strip$(HOST_EXECUTABLE_SUFFIX)
+$(combo_2nd_arch_prefix)TARGET_CC := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)gcc
+$(combo_2nd_arch_prefix)TARGET_CXX := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)g++
+$(combo_2nd_arch_prefix)TARGET_AR := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ar
+$(combo_2nd_arch_prefix)TARGET_OBJCOPY := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)objcopy
+$(combo_2nd_arch_prefix)TARGET_LD := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ld
+$(combo_2nd_arch_prefix)TARGET_READELF := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)readelf
+$(combo_2nd_arch_prefix)TARGET_STRIP := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)strip
 
 $(combo_2nd_arch_prefix)TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
 
@@ -162,7 +162,7 @@
 $(combo_2nd_arch_prefix)TARGET_CRTBEGIN_SO_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
 $(combo_2nd_arch_prefix)TARGET_CRTEND_SO_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
 
-$(combo_2nd_arch_prefix)TARGET_STRIP_MODULE:=true
+$(combo_2nd_arch_prefix)TARGET_PACK_MODULE_RELOCATIONS := true
 
 $(combo_2nd_arch_prefix)TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libm
 
diff --git a/core/combo/TARGET_linux-mips64.mk b/core/combo/TARGET_linux-mips64.mk
index c6f9f29..1116f46 100644
--- a/core/combo/TARGET_linux-mips64.mk
+++ b/core/combo/TARGET_linux-mips64.mk
@@ -57,13 +57,13 @@
 TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/mips64el-linux-android-
 endif
 
-TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
-TARGET_CXX := $(TARGET_TOOLS_PREFIX)g++$(HOST_EXECUTABLE_SUFFIX)
-TARGET_AR := $(TARGET_TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
-TARGET_OBJCOPY := $(TARGET_TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
-TARGET_LD := $(TARGET_TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
-TARGET_READELF := $(TARGET_TOOLS_PREFIX)readelf$(HOST_EXECUTABLE_SUFFIX)
-TARGET_STRIP := $(TARGET_TOOLS_PREFIX)strip$(HOST_EXECUTABLE_SUFFIX)
+TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc
+TARGET_CXX := $(TARGET_TOOLS_PREFIX)g++
+TARGET_AR := $(TARGET_TOOLS_PREFIX)ar
+TARGET_OBJCOPY := $(TARGET_TOOLS_PREFIX)objcopy
+TARGET_LD := $(TARGET_TOOLS_PREFIX)ld
+TARGET_READELF := $(TARGET_TOOLS_PREFIX)readelf
+TARGET_STRIP := $(TARGET_TOOLS_PREFIX)strip
 
 TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
 
@@ -169,7 +169,7 @@
 TARGET_CRTBEGIN_SO_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
 TARGET_CRTEND_SO_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
 
-TARGET_STRIP_MODULE:=true
+TARGET_PACK_MODULE_RELOCATIONS := true
 
 TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
 
diff --git a/core/combo/TARGET_linux-x86.mk b/core/combo/TARGET_linux-x86.mk
index f17a514..482889d 100644
--- a/core/combo/TARGET_linux-x86.mk
+++ b/core/combo/TARGET_linux-x86.mk
@@ -23,10 +23,10 @@
 endif
 
 # Decouple NDK library selection with platform compiler version
-$(combo_2nd_arch_prefix)TARGET_NDK_GCC_VERSION := 4.8
+$(combo_2nd_arch_prefix)TARGET_NDK_GCC_VERSION := 4.9
 
 ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
-$(combo_2nd_arch_prefix)TARGET_GCC_VERSION := 4.8
+$(combo_2nd_arch_prefix)TARGET_GCC_VERSION := 4.9
 else
 $(combo_2nd_arch_prefix)TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
 endif
@@ -49,13 +49,13 @@
 $(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX := $($(combo_2nd_arch_prefix)TARGET_TOOLCHAIN_ROOT)/bin/x86_64-linux-android-
 endif
 
-$(combo_2nd_arch_prefix)TARGET_CC := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_CXX := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)g++$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_AR := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_OBJCOPY := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_LD := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_READELF := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)readelf$(HOST_EXECUTABLE_SUFFIX)
-$(combo_2nd_arch_prefix)TARGET_STRIP := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)strip$(HOST_EXECUTABLE_SUFFIX)
+$(combo_2nd_arch_prefix)TARGET_CC := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)gcc
+$(combo_2nd_arch_prefix)TARGET_CXX := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)g++
+$(combo_2nd_arch_prefix)TARGET_AR := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ar
+$(combo_2nd_arch_prefix)TARGET_OBJCOPY := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)objcopy
+$(combo_2nd_arch_prefix)TARGET_LD := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)ld
+$(combo_2nd_arch_prefix)TARGET_READELF := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)readelf
+$(combo_2nd_arch_prefix)TARGET_STRIP := $($(combo_2nd_arch_prefix)TARGET_TOOLS_PREFIX)strip
 
 ifneq ($(wildcard $($(combo_2nd_arch_prefix)TARGET_CC)),)
 $(combo_2nd_arch_prefix)TARGET_LIBGCC := \
@@ -97,6 +97,10 @@
 			-include $(android_config_h) \
 			-I $(dir $(android_config_h))
 
+# Work around gcc 4.9 devirtualization bug, https://b.corp.google.com/19872411.
+$(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += \
+			-fno-devirtualize \
+
 $(combo_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS += $(arch_variant_cflags)
 
 ifeq ($(ARCH_X86_HAVE_SSSE3),true)   # yes, really SSSE3, not SSE3!
@@ -142,7 +146,7 @@
 $(combo_2nd_arch_prefix)TARGET_CRTBEGIN_SO_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
 $(combo_2nd_arch_prefix)TARGET_CRTEND_SO_O := $($(combo_2nd_arch_prefix)TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
 
-$(combo_2nd_arch_prefix)TARGET_STRIP_MODULE:=true
+$(combo_2nd_arch_prefix)TARGET_PACK_MODULE_RELOCATIONS := true
 
 $(combo_2nd_arch_prefix)TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libm
 
diff --git a/core/combo/TARGET_linux-x86_64.mk b/core/combo/TARGET_linux-x86_64.mk
index 2adb157..c705b95 100644
--- a/core/combo/TARGET_linux-x86_64.mk
+++ b/core/combo/TARGET_linux-x86_64.mk
@@ -26,7 +26,7 @@
 TARGET_NDK_GCC_VERSION := 4.9
 
 ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
-TARGET_GCC_VERSION := 4.8
+TARGET_GCC_VERSION := 4.9
 else
 TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
 endif
@@ -49,13 +49,13 @@
 TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/x86_64-linux-android-
 endif
 
-TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
-TARGET_CXX := $(TARGET_TOOLS_PREFIX)g++$(HOST_EXECUTABLE_SUFFIX)
-TARGET_AR := $(TARGET_TOOLS_PREFIX)ar$(HOST_EXECUTABLE_SUFFIX)
-TARGET_OBJCOPY := $(TARGET_TOOLS_PREFIX)objcopy$(HOST_EXECUTABLE_SUFFIX)
-TARGET_LD := $(TARGET_TOOLS_PREFIX)ld$(HOST_EXECUTABLE_SUFFIX)
-TARGET_READELF := $(TARGET_TOOLS_PREFIX)readelf$(HOST_EXECUTABLE_SUFFIX)
-TARGET_STRIP := $(TARGET_TOOLS_PREFIX)strip$(HOST_EXECUTABLE_SUFFIX)
+TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc
+TARGET_CXX := $(TARGET_TOOLS_PREFIX)g++
+TARGET_AR := $(TARGET_TOOLS_PREFIX)ar
+TARGET_OBJCOPY := $(TARGET_TOOLS_PREFIX)objcopy
+TARGET_LD := $(TARGET_TOOLS_PREFIX)ld
+TARGET_READELF := $(TARGET_TOOLS_PREFIX)readelf
+TARGET_STRIP := $(TARGET_TOOLS_PREFIX)strip
 
 ifneq ($(wildcard $(TARGET_CC)),)
 TARGET_LIBGCC := \
@@ -93,6 +93,10 @@
 			-no-canonical-prefixes \
 			-fno-canonical-system-headers
 
+# Work around gcc 4.9 devirtualization bug, https://b.corp.google.com/19872411.
+TARGET_GLOBAL_CFLAGS += \
+			-fno-devirtualize \
+
 # Help catch common 32/64-bit errors.
 TARGET_GLOBAL_CFLAGS += \
     -Werror=pointer-to-int-cast \
@@ -151,8 +155,6 @@
 TARGET_CRTBEGIN_SO_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_so.o
 TARGET_CRTEND_SO_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_so.o
 
-TARGET_STRIP_MODULE:=true
-
 TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libm
 
 TARGET_LINKER := /system/bin/linker64
diff --git a/core/combo/arch/arm/armv7-a-neon.mk b/core/combo/arch/arm/armv7-a-neon.mk
index d535afc..99f17aa 100644
--- a/core/combo/arch/arm/armv7-a-neon.mk
+++ b/core/combo/arch/arm/armv7-a-neon.mk
@@ -16,14 +16,23 @@
 	# Fake an ARM compiler flag as these processors support LPAE which GCC/clang
 	# don't advertise.
 	arch_variant_cflags += -D__ARM_FEATURE_LPAE=1
+	arch_variant_ldflags := \
+		-Wl,--no-fix-cortex-a8
 else
 ifeq ($(strip $(TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT)),cortex-a8)
 	arch_variant_cflags := -mcpu=cortex-a8
+	arch_variant_ldflags := \
+		-Wl,--fix-cortex-a8
 else
 ifeq ($(strip $(TARGET_$(combo_2nd_arch_prefix)CPU_VARIANT)),cortex-a7)
 	arch_variant_cflags := -mcpu=cortex-a7
+	arch_variant_ldflags := \
+		-Wl,--no-fix-cortex-a8
 else
 	arch_variant_cflags := -march=armv7-a
+	# Generic ARM might be a Cortex A8 -- better safe than sorry
+	arch_variant_ldflags := \
+		-Wl,--fix-cortex-a8
 endif
 endif
 endif
@@ -31,6 +40,3 @@
 arch_variant_cflags += \
     -mfloat-abi=softfp \
     -mfpu=neon
-
-arch_variant_ldflags := \
-	-Wl,--fix-cortex-a8
diff --git a/core/config.mk b/core/config.mk
index 0b76b53..83295d9 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -131,9 +131,6 @@
 # list of flags to turn specific warnings in to errors
 TARGET_ERROR_FLAGS := -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point
 
-# TODO: do symbol compression
-TARGET_COMPRESS_MODULE_SYMBOLS := false
-
 # ###############################################################
 # Include sub-configuration files
 # ###############################################################
@@ -428,6 +425,10 @@
 # dx is java behind a shell script; no .exe necessary.
 DX := $(HOST_OUT_EXECUTABLES)/dx
 ZIPALIGN := $(HOST_OUT_EXECUTABLES)/zipalign$(HOST_EXECUTABLE_SUFFIX)
+
+# relocation packer
+RELOCATION_PACKER := prebuilts/misc/$(BUILD_OS)-$(HOST_PREBUILT_ARCH)/relocation_packer/relocation_packer
+
 FINDBUGS_DIR := external/owasp/sanitizer/tools/findbugs/bin
 FINDBUGS := $(FINDBUGS_DIR)/findbugs
 EMMA_JAR := external/emma/lib/emma$(COMMON_JAVA_PACKAGE_SUFFIX)
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index a1964a9..b116283 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -2,31 +2,106 @@
 ## Perform configuration steps for sanitizers.
 ##############################################
 
-# Configure SANITIZE_HOST.
-ifdef LOCAL_IS_HOST_MODULE
-ifeq ($(SANITIZE_HOST),true)
-ifneq ($(strip $(LOCAL_CLANG)),false)
-ifneq ($(strip $(LOCAL_ADDRESS_SANITIZER)),false)
-    LOCAL_ADDRESS_SANITIZER := true
-endif
-endif
-endif
+my_sanitize := $(strip $(LOCAL_SANITIZE))
+
+# Keep compatibility for LOCAL_ADDRESS_SANITIZER until all targets have moved to
+# `LOCAL_SANITIZE := address`.
+ifeq ($(strip $(LOCAL_ADDRESS_SANITIZER)),true)
+  my_sanitize += address
 endif
 
-# Configure address sanitizer.
-ifeq ($(strip $(LOCAL_ADDRESS_SANITIZER)),true)
-  my_clang := true
+# And `LOCAL_SANITIZE := never`.
+ifeq ($(strip $(LOCAL_ADDRESS_SANITIZER)),false)
+  my_sanitize := never
+endif
+
+# Don't apply sanitizers to NDK code.
+ifdef LOCAL_SDK_VERSION
+  my_sanitize := never
+endif
+
+# Configure SANITIZE_HOST.
+ifdef LOCAL_IS_HOST_MODULE
+  ifeq ($(my_sanitize),)
+    my_sanitize := $(strip $(SANITIZE_HOST))
+
+    # SANTIZIZE_HOST=true is a deprecated way to say SANITIZE_HOST=address.
+    ifeq ($(my_sanitize),true)
+      my_sanitize := address
+    endif
+
+    # SANITIZE_HOST is only in effect if the module is already using clang (host
+    # modules that haven't set `LOCAL_CLANG := false` and device modules that
+    # have set `LOCAL_CLANG := true`.
+    ifneq ($(my_clang),true)
+      my_sanitize :=
+    endif
+  endif
+endif
+
+ifeq ($(my_sanitize),never)
+  my_sanitize :=
+endif
+
+# Sanitizers can only be used with clang.
+ifneq ($(my_clang),true)
+  ifneq ($(my_sanitize),)
+    $(error $(LOCAL_PATH): $(LOCAL_MODULE): Use of sanitizers requires LOCAL_CLANG := true)
+  endif
+endif
+
+ifneq ($(filter default-ub,$(my_sanitize)),)
+  my_sanitize := $(CLANG_DEFAULT_UB_CHECKS)
+  my_ldlibs += -ldl
+
+  ifdef LOCAL_IS_HOST_MODULE
+    my_cflags += -fno-sanitize-recover=all
+  else
+    my_cflags += -fsanitize-undefined-trap-on-error
+  endif
+endif
+
+ifneq ($(my_sanitize),)
+  fsanitize_arg := $(subst $(space),$(comma),$(my_sanitize)),
+  my_cflags += -fsanitize=$(fsanitize_arg)
+
+  ifdef LOCAL_IS_HOST_MODULE
+    my_ldflags += -fsanitize=$(fsanitize_arg)
+  endif
+endif
+
+ifneq ($(filter address,$(my_sanitize)),)
   # Frame pointer based unwinder in ASan requires ARM frame setup.
   LOCAL_ARM_MODE := arm
   my_cflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS)
   my_ldflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS)
   ifdef LOCAL_IS_HOST_MODULE
-      my_ldflags += -fsanitize=address
-      # -nodefaultlibs (provided with libc++) prevents the driver from linking
-      # libraries needed with -fsanitize=address. http://b/18650275
-      my_ldlibs += -ldl -lpthread
+    # -nodefaultlibs (provided with libc++) prevents the driver from linking
+    # libraries needed with -fsanitize=address. http://b/18650275 (WAI)
+    my_ldlibs += -lm -ldl -lpthread
+    my_ldflags += -Wl,--no-as-needed
   else
-      my_shared_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES)
-      my_static_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES)
+    # ASan runtime library must be the first in the link order.
+    my_shared_libraries := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_RUNTIME_LIBRARY) \
+                           $(my_shared_libraries) \
+                           $(ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES)
+    my_static_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES)
+    my_ldflags += -Wl,-rpath,$($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_RPATH)
   endif
 endif
+
+ifneq ($(filter undefined,$(my_sanitize)),)
+  my_cflags += -fno-sanitize-recover=all
+
+  ifdef LOCAL_IS_HOST_MODULE
+    my_ldlibs += -ldl
+  else
+    $(error ubsan is not yet supported on the target)
+  endif
+endif
+
+
+ifneq ($(strip $(LOCAL_SANITIZE_RECOVER)),)
+  recover_arg := $(subst $(space),$(comma),$(LOCAL_SANITIZE_RECOVER)),
+  my_cflags += -fsanitize-recover=$(recover_arg)
+endif
diff --git a/core/cxx_stl_setup.mk b/core/cxx_stl_setup.mk
index 7961801..c59cd34 100644
--- a/core/cxx_stl_setup.mk
+++ b/core/cxx_stl_setup.mk
@@ -8,16 +8,16 @@
 ifeq ($(strip $(LOCAL_CXX_STL)),default)
     ifndef LOCAL_SDK_VERSION
         # Platform code. Select the appropriate STL.
-        ifndef USE_MINGW
-            my_cxx_stl := libc++
-            ifdef LOCAL_IS_HOST_MODULE
-                ifneq (,$(BUILD_HOST_static))
-                    my_cxx_stl := libc++_static
-                endif
+        my_cxx_stl := libc++
+        ifdef LOCAL_IS_HOST_MODULE
+            ifneq (,$(BUILD_HOST_static))
+                my_cxx_stl := libc++_static
             endif
-        else
-            # libc++ is not supported on mingw.
-            my_cxx_stl := libstdc++
+
+            ifdef USE_MINGW
+                # libc++ is not supported on mingw.
+                my_cxx_stl := libstdc++
+            endif
         endif
     else
         my_cxx_stl := ndk
@@ -49,15 +49,17 @@
 ifneq ($(filter $(my_cxx_stl),libc++ libc++_static),)
     my_cflags += -D_USING_LIBCXX
     my_c_includes += external/libcxx/include
-    ifeq ($(my_cxx_stl),libc++)
-        my_shared_libraries += libc++
+
+    # Note that the structure of this means that LOCAL_CXX_STL := libc++ will
+    # use the static libc++ for static executables.
+    ifeq ($(my_link_type),dynamic)
+        ifeq ($(my_cxx_stl),libc++)
+            my_shared_libraries += libc++
+        else
+            my_static_libraries += libc++_static
+        endif
     else
         my_static_libraries += libc++_static
-        ifndef LOCAL_IS_HOST_MODULE
-            ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
-                my_static_libraries += libm libc libdl
-            endif
-        endif
     endif
 
     ifdef LOCAL_IS_HOST_MODULE
@@ -68,28 +70,16 @@
     else
         ifeq (arm,$($(my_prefix)$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH))
             my_static_libraries += libunwind_llvm
-        else
-            my_static_libraries += libunwindbacktrace
         endif
 
         ifeq ($(my_link_type),static)
-            my_static_libraries += libdl
+            my_static_libraries += libm libc libdl
         else
             my_shared_libraries += libdl
         endif
     endif
-else ifneq ($(filter $(my_cxx_stl),stlport stlport_static),)
-    ifndef LOCAL_IS_HOST_MODULE
-        my_c_includes += external/stlport/stlport bionic/libstdc++/include \
-                         bionic
-        ifeq ($(my_cxx_stl),stlport)
-            my_shared_libraries += libstdc++ libstlport
-        else
-            my_static_libraries += libstdc++ libstlport_static
-        endif
-    endif
 else ifeq ($(my_cxx_stl),ndk)
-    # Using an NDK STL. Handled farther up in this file.
+    # Using an NDK STL. Handled in binary.mk.
     ifndef LOCAL_IS_HOST_MODULE
         my_system_shared_libraries += libstdc++
     endif
@@ -108,5 +98,5 @@
         my_ldlibs += $($(my_prefix)$(HOST_OS)_$(my_link_type)_gcclibs)
     endif
 else
-    $(error $(my_cxx_stl) is not a supported STL.)
+    $(error $(LOCAL_PATH): $(LOCAL_MODULE): $(my_cxx_stl) is not a supported STL.)
 endif
diff --git a/core/definitions.mk b/core/definitions.mk
index e56e0db..b6e5277 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -1452,6 +1452,15 @@
     $(TARGET_STRIP_KEEP_SYMBOLS_EXTRA) $< $@
 endef
 
+###########################################################
+## Commands for packing a target executable or library
+###########################################################
+
+define pack-elf-relocations
+$(copy-file-to-target)
+@echo "target Pack Relocations: $(PRIVATE_MODULE) ($@)"
+$(hide) $(RELOCATION_PACKER) $@
+endef
 
 ###########################################################
 ## Commands for running gcc to link an executable
@@ -1903,7 +1912,8 @@
 $(foreach abi,$(PRIVATE_JNI_SHARED_LIBRARIES_ABI),\
   $(call _add-jni-shared-libs-to-package-per-abi,$(abi),\
     $(patsubst $(abi):%,%,$(filter $(abi):%,$(PRIVATE_JNI_SHARED_LIBRARIES)))))
-$(hide) (cd $(dir $@) && zip -r $(PRIVATE_JNI_SHARED_LIBRARIES_ZIP_OPTIONS) $(notdir $@) lib)
+$(hide) (cd $(dir $@) && zip -r \
+    $(if $(filter true, $(PRIVATE_PAGE_ALIGN_JNI_SHARED_LIBRARIES)),-0,) $(notdir $@) lib)
 $(hide) rm -rf $(dir $@)lib
 endef
 
@@ -1937,12 +1947,22 @@
 $(hide) mv $@ $@.unaligned
 $(hide) $(ZIPALIGN) \
     -f \
-    $(if $(findstring true, $(PRIVATE_PAGE_ALIGN_JNI_SHARED_LIBRARIES)),-p ,) \
+    $(if $(filter true, $(PRIVATE_PAGE_ALIGN_JNI_SHARED_LIBRARIES)),-p,) \
     4 \
     $@.unaligned $@.aligned
 $(hide) mv $@.aligned $@
 endef
 
+define uncompress-shared-libs
+$(hide) rm -rf $(dir $@)/tmpworkdir
+$(hide) mv $@ $@.compressed
+$(hide) mkdir $(dir $@)/tmpworkdir
+$(hide) unzip $@.compressed 'lib/*.so' -d $(dir $@)/tmpworkdir
+$(hide) ( cd $(dir $@)/tmpworkdir && zip -D -r -0 ../$(notdir $@).compressed lib )
+$(hide) mv $@.compressed $@
+$(hide) rm -rf $(dir $@)/tmpworkdir
+endef
+
 define install-dex-debug
 $(hide) if [ -f "$(PRIVATE_INTERMEDIATES_DIR)/classes.dex" ]; then \
 	    mkdir -p $(TOP)/dalvik/DEBUG-FILES; \
@@ -2091,32 +2111,6 @@
   $(hide) mkdir -p $(dir $(3)/$(s)); cp -Rf $(t) $(3)/$(s)$(newline))
 endef
 
-###########################################################
-## On some platforms (MacOS), after copying a static
-## library, ranlib must be run to update an internal
-## timestamp!?!?!
-###########################################################
-
-ifeq ($(HOST_RUN_RANLIB_AFTER_COPYING),true)
-define transform-host-ranlib-copy-hack
-    $(hide) ranlib $@ || true
-endef
-else
-define transform-host-ranlib-copy-hack
-@true
-endef
-endif
-
-ifeq ($(TARGET_RUN_RANLIB_AFTER_COPYING),true)
-define transform-ranlib-copy-hack
-    $(hide) ranlib $@
-endef
-else
-define transform-ranlib-copy-hack
-@true
-endef
-endif
-
 
 ###########################################################
 ## Commands to call Proguard
diff --git a/core/dex_preopt_libart.mk b/core/dex_preopt_libart.mk
index fb62e0c..6f598be 100644
--- a/core/dex_preopt_libart.mk
+++ b/core/dex_preopt_libart.mk
@@ -105,7 +105,7 @@
 	--instruction-set=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH) \
 	--instruction-set-variant=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT) \
 	--instruction-set-features=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) \
-	--include-patch-information --runtime-arg -Xnorelocate --no-include-debug-symbols \
+	--include-patch-information --runtime-arg -Xnorelocate --no-include-debug-symbols --no-include-cfi \
 	--abort-on-hard-verifier-error \
 	$(PRIVATE_DEX_PREOPT_FLAGS)
 endef
diff --git a/core/dex_preopt_libart_boot.mk b/core/dex_preopt_libart_boot.mk
index 2569d73..cfc7653 100644
--- a/core/dex_preopt_libart_boot.mk
+++ b/core/dex_preopt_libart_boot.mk
@@ -62,5 +62,5 @@
 		--instruction-set=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_ARCH) \
 		--instruction-set-variant=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_CPU_VARIANT) \
 		--instruction-set-features=$($(PRIVATE_2ND_ARCH_VAR_PREFIX)DEX2OAT_TARGET_INSTRUCTION_SET_FEATURES) \
-		--android-root=$(PRODUCT_OUT)/system --include-patch-information --runtime-arg -Xnorelocate --no-include-debug-symbols \
+		--android-root=$(PRODUCT_OUT)/system --include-patch-information --runtime-arg -Xnorelocate --no-include-debug-symbols --no-include-cfi \
 		$(PRODUCT_DEX_PREOPT_BOOT_FLAGS) $(COMPILED_CLASSES_FLAGS)
diff --git a/core/dynamic_binary.mk b/core/dynamic_binary.mk
index cf06a3d..38c0cbe 100644
--- a/core/dynamic_binary.mk
+++ b/core/dynamic_binary.mk
@@ -39,27 +39,37 @@
 ###################################
 
 ###########################################################
-## Compress
+## Pack relocation tables
 ###########################################################
-compress_input := $(linked_module)
+relocation_packer_input := $(linked_module)
+relocation_packer_output := $(intermediates)/PACKED/$(my_built_module_stem)
 
-ifeq ($(strip $(LOCAL_COMPRESS_MODULE_SYMBOLS)),)
-  LOCAL_COMPRESS_MODULE_SYMBOLS := $(strip $(TARGET_COMPRESS_MODULE_SYMBOLS))
+my_pack_module_relocations := $(LOCAL_PACK_MODULE_RELOCATIONS)
+
+ifeq ($(my_pack_module_relocations),)
+  my_pack_module_relocations := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_PACK_MODULE_RELOCATIONS)
 endif
 
-ifeq ($(LOCAL_COMPRESS_MODULE_SYMBOLS),true)
-$(error Symbol compression not yet supported.)
-compress_output := $(intermediates)/COMPRESSED-$(my_built_module_stem)
+# Do not pack relocations for executables. Because packing results in
+# non-zero p_vaddr which causes kernel to load executables to lower
+# address (starting at 0x8000) http://b/20665974
+ifeq ($(LOCAL_MODULE_CLASS),EXECUTABLES)
+  my_pack_module_relocations := false
+endif
 
-#TODO: write the real $(STRIPPER) rule.
-#TODO: define a rule to build TARGET_SYMBOL_FILTER_FILE, and
-#      make it depend on ALL_ORIGINAL_DYNAMIC_BINARIES.
-$(compress_output): $(compress_input) $(TARGET_SYMBOL_FILTER_FILE) | $(ACP)
-	@echo "target Compress Symbols: $(PRIVATE_MODULE) ($@)"
-	$(copy-file-to-target)
+# TODO (dimitry): Relocation packer is not yet available for darwin
+ifneq ($(HOST_OS),linux)
+  my_pack_module_relocations := false
+endif
+
+ifeq (true,$(my_pack_module_relocations))
+# Pack relocations
+$(relocation_packer_output): $(relocation_packer_input) | $(ACP)
+	$(pack-elf-relocations)
 else
-# Skip this step.
-compress_output := $(compress_input)
+$(relocation_packer_output): $(relocation_packer_input) | $(ACP)
+	@echo "target Unpacked: $(PRIVATE_MODULE) ($@)"
+	$(copy-file-to-target)
 endif
 
 ###########################################################
@@ -70,7 +80,7 @@
 else
 my_unstripped_path := $(LOCAL_UNSTRIPPED_PATH)
 endif
-symbolic_input := $(compress_output)
+symbolic_input := $(relocation_packer_output)
 symbolic_output := $(my_unstripped_path)/$(my_installed_module_stem)
 $(symbolic_output) : $(symbolic_input) | $(ACP)
 	@echo "target Symbolic: $(PRIVATE_MODULE) ($@)"
@@ -85,7 +95,7 @@
 
 my_strip_module := $(LOCAL_STRIP_MODULE)
 ifeq ($(my_strip_module),)
-  my_strip_module := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP_MODULE)
+  my_strip_module := true
 endif
 
 $(strip_output): PRIVATE_STRIP := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_STRIP)
@@ -131,8 +141,7 @@
 endif
 endif # my_strip_module
 
-
 $(cleantarget): PRIVATE_CLEAN_FILES += \
     $(linked_module) \
     $(symbolic_output) \
-    $(compress_output)
+    $(strip_output)
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 75391e1..015cfee 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -100,11 +100,7 @@
 HOST_PREBUILT_ARCH := x86
 # This is the standard way to name a directory containing prebuilt host
 # objects. E.g., prebuilt/$(HOST_PREBUILT_TAG)/cc
-ifeq ($(HOST_OS),windows)
-  HOST_PREBUILT_TAG := windows
-else
-  HOST_PREBUILT_TAG := $(HOST_OS)-$(HOST_PREBUILT_ARCH)
-endif
+HOST_PREBUILT_TAG := $(BUILD_OS)-$(HOST_PREBUILT_ARCH)
 
 # TARGET_COPY_OUT_* are all relative to the staging directory, ie PRODUCT_OUT.
 # Define them here so they can be used in product config files.
@@ -259,6 +255,7 @@
 $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_INTERMEDIATE_LIBRARIES := $($(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_INTERMEDIATES)/lib
 $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_SHARED_LIBRARIES := $(HOST_OUT)/lib
 $(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_EXECUTABLES := $(HOST_OUT_EXECUTABLES)
+$(HOST_2ND_ARCH_VAR_PREFIX)HOST_OUT_JAVA_LIBRARIES := $(HOST_OUT_JAVA_LIBRARIES)
 
 # The default host library path.
 # It always points to the path where we build libraries in the default bitness.
diff --git a/core/host_shared_library.mk b/core/host_shared_library.mk
index 438a9ce..e840780 100644
--- a/core/host_shared_library.mk
+++ b/core/host_shared_library.mk
@@ -6,8 +6,8 @@
 ifeq ($(HOST_PREFER_32_BIT),true)
 my_module_multilib := 32
 else
-# By default we only build host module for the first arch.
-my_module_multilib := first
+# libraries default to building for both architecturess
+my_module_multilib := both
 endif
 endif
 endif
diff --git a/core/host_static_library.mk b/core/host_static_library.mk
index 74ac2ea..52c42ef 100644
--- a/core/host_static_library.mk
+++ b/core/host_static_library.mk
@@ -6,8 +6,8 @@
 ifeq ($(HOST_PREFER_32_BIT),true)
 my_module_multilib := 32
 else
-# By default we only build host module for the first arch.
-my_module_multilib := first
+# libraries default to building for both architecturess
+my_module_multilib := both
 endif
 endif
 endif
diff --git a/core/main.mk b/core/main.mk
index 13465e3..3bb8c04 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -29,7 +29,7 @@
 # TOPDIR is the normal variable you should use, because
 # if we are executing relative to the current directory
 # it can be "", whereas TOP must be "." which causes
-# pattern matching probles when make strips off the
+# pattern matching problems when make strips off the
 # trailing "./" from paths in various places.
 #ifeq ($(TOP),.)
 #TOPDIR :=
@@ -175,7 +175,7 @@
 #
 # For Java 1.7, we require OpenJDK on linux and Oracle JDK on Mac OS.
 requires_openjdk := false
-ifeq ($(HOST_OS), linux)
+ifeq ($(BUILD_OS),linux)
 requires_openjdk := true
 endif
 
diff --git a/core/multilib.mk b/core/multilib.mk
index a3ced65..e0615b2 100644
--- a/core/multilib.mk
+++ b/core/multilib.mk
@@ -13,3 +13,11 @@
 $(error $(LOCAL_PATH): Invalid LOCAL_MULTILIB specified for module $(LOCAL_MODULE))
 endif
 endif # my_module_multilib defined
+
+# Windows is a special case. Linux and Darwin are both multilib builds, but we
+# don't have a 64-bit Windows build, so make sure it's not a multilib build.
+ifdef LOCAL_IS_HOST_MODULE
+ifeq ($(HOST_OS),windows)
+my_module_multilib := 32
+endif
+endif
diff --git a/core/package_internal.mk b/core/package_internal.mk
index 5dac455..d52997b 100644
--- a/core/package_internal.mk
+++ b/core/package_internal.mk
@@ -369,7 +369,6 @@
 $(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES := $(jni_shared_libraries_with_abis)
 # PRIVATE_JNI_SHARED_LIBRARIES_ABI is a list of ABI names.
 $(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES_ABI := $(jni_shared_libraries_abis)
-$(LOCAL_BUILT_MODULE): PRIVATE_JNI_SHARED_LIBRARIES_ZIP_OPTIONS := $(LOCAL_JNI_SHARED_LIBRARIES_ZIP_OPTIONS)
 $(LOCAL_BUILT_MODULE): PRIVATE_PAGE_ALIGN_JNI_SHARED_LIBRARIES := $(LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES)
 ifneq ($(TARGET_BUILD_APPS),)
     # Include all resources for unbundled apps.
@@ -402,12 +401,12 @@
 else
 	$(add-dex-to-package)
 endif
-	$(sign-package)
 ifdef LOCAL_DEX_PREOPT
 ifneq (nostripping,$(LOCAL_DEX_PREOPT))
 	$(call dexpreopt-remove-classes.dex,$@)
 endif
 endif
+	$(sign-package)
 	@# Alignment must happen after all other zip operations.
 	$(align-package)
 
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 47e21ef..f85b0b8 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -43,6 +43,11 @@
     # Strip but not try to add debuglink
     LOCAL_STRIP_MODULE := no_debuglink
   endif
+
+  ifeq ($(LOCAL_IS_HOST_MODULE)$(LOCAL_PACK_MODULE_RELOCATIONS),)
+    # Do not pack relocations by default
+    LOCAL_PACK_MODULE_RELOCATIONS := false
+  endif
 endif
 
 ifneq ($(filter STATIC_LIBRARIES SHARED_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
@@ -63,20 +68,20 @@
 LOCAL_INSTALLED_MODULE_STEM := $(LOCAL_MODULE).apk
 endif
 
-ifneq ($(filter true no_debuglink,$(LOCAL_STRIP_MODULE)),)
+ifneq ($(filter true no_debuglink,$(LOCAL_STRIP_MODULE) $(LOCAL_PACK_MODULE_RELOCATIONS)),)
   ifdef LOCAL_IS_HOST_MODULE
-    $(error Cannot strip host module LOCAL_PATH=$(LOCAL_PATH))
+    $(error Cannot strip/pack host module LOCAL_PATH=$(LOCAL_PATH))
   endif
   ifeq ($(filter SHARED_LIBRARIES EXECUTABLES,$(LOCAL_MODULE_CLASS)),)
-    $(error Can strip only shared libraries or executables LOCAL_PATH=$(LOCAL_PATH))
+    $(error Can strip/pack only shared libraries or executables LOCAL_PATH=$(LOCAL_PATH))
   endif
   ifneq ($(LOCAL_PREBUILT_STRIP_COMMENTS),)
-    $(error Cannot strip scripts LOCAL_PATH=$(LOCAL_PATH))
+    $(error Cannot strip/pack scripts LOCAL_PATH=$(LOCAL_PATH))
   endif
   include $(BUILD_SYSTEM)/dynamic_binary.mk
   built_module := $(linked_module)
 
-else  # LOCAL_STRIP_MODULE not true
+else  # LOCAL_STRIP_MODULE and LOCAL_PACK_MODULE_RELOCATIONS not true
   include $(BUILD_SYSTEM)/base_rules.mk
   built_module := $(LOCAL_BUILT_MODULE)
 
@@ -193,17 +198,21 @@
 $(built_module) : PRIVATE_PAGE_ALIGN_JNI_SHARED_LIBRARIES := $(LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES)
 $(built_module) : $(my_prebuilt_src_file) | $(ACP) $(ZIPALIGN) $(SIGNAPK_JAR)
 	$(transform-prebuilt-to-target)
+ifneq ($(LOCAL_CERTIFICATE),PRESIGNED)
+	@# Only strip out files if we can re-sign the package.
 ifdef extracted_jni_libs
 	$(hide) zip -d $@ 'lib/*.so'  # strip embedded JNI libraries.
 endif
-ifneq ($(LOCAL_CERTIFICATE),PRESIGNED)
-	$(sign-package)
-endif
 ifdef LOCAL_DEX_PREOPT
 ifneq (nostripping,$(LOCAL_DEX_PREOPT))
 	$(call dexpreopt-remove-classes.dex,$@)
 endif
 endif
+	$(sign-package)
+endif
+ifeq ($(LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES),true)
+	$(uncompress-shared-libs)
+endif
 	$(align-package)
 
 ###############################
@@ -256,13 +265,6 @@
 else
 $(built_module) : $(my_prebuilt_src_file) | $(ACP)
 	$(transform-prebuilt-to-target)
-ifneq ($(prebuilt_module_is_a_library),)
-  ifneq ($(LOCAL_IS_HOST_MODULE),)
-	$(transform-host-ranlib-copy-hack)
-  else
-	$(transform-ranlib-copy-hack)
-  endif
-endif
 endif
 endif # LOCAL_MODULE_CLASS != APPS
 
diff --git a/core/product.mk b/core/product.mk
index d3df582..46fad89 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -229,7 +229,6 @@
 	TARGET_DEVICE_KERNEL_HEADERS \
 	TARGET_PRODUCT_KERNEL_HEADERS \
 	TARGET_BOOTLOADER_BOARD_NAME \
-	TARGET_COMPRESS_MODULE_SYMBOLS \
 	TARGET_NO_BOOTLOADER \
 	TARGET_NO_KERNEL \
 	TARGET_NO_RECOVERY \
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
index ee17444..23648f8 100644
--- a/core/tasks/cts.mk
+++ b/core/tasks/cts.mk
@@ -65,7 +65,7 @@
 
 CTS_TEST_JAR_LIST := \
         cts-junit \
-	CtsJdwp
+        CtsJdwp
 
 # Depend on the full package paths rather than the phony targets to avoid
 # rebuilding the packages every time.
@@ -86,8 +86,11 @@
     $(eval $(call copy-one-file, $(built), $(installed)))\
     $(eval CTS_CASE_LIST_APKS += $(installed))))
 
+CTS_SHARED_LIBS := \
+	$(HOST_LIBRARY_PATH)/libc++$(HOST_SHLIB_SUFFIX)
+
 DEFAULT_TEST_PLAN := $(cts_dir)/$(cts_name)/resource/plans
-$(cts_dir)/all_cts_files_stamp: $(CTS_CORE_CASES) $(CTS_TEST_CASES) $(CTS_CASE_LIST_APKS) $(JUNIT_HOST_JAR) $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(TF_JAR) $(VMTESTSTF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(CTS_TF_README_PATH) $(ACP) $(CTS_TEST_JAR_FILES)
+$(cts_dir)/all_cts_files_stamp: $(CTS_CORE_CASES) $(CTS_TEST_CASES) $(CTS_CASE_LIST_APKS) $(JUNIT_HOST_JAR) $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(TF_JAR) $(VMTESTSTF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(CTS_TF_README_PATH) $(ACP) $(CTS_TEST_JAR_FILES) $(CTS_SHARED_LIBS)
 # Make necessary directory for CTS
 	$(hide) mkdir -p $(TMP_DIR)
 	$(hide) mkdir -p $(PRIVATE_DIR)/docs
@@ -97,6 +100,7 @@
 # Copy executable and JARs to CTS directory
 	$(hide) $(ACP) -fp $(VMTESTSTF_JAR) $(PRIVATE_DIR)/repository/testcases
 	$(hide) $(ACP) -fp $(HOSTTESTLIB_JAR) $(CTS_HOST_LIBRARY_JARS) $(TF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(CTS_TF_README_PATH) $(PRIVATE_DIR)/tools
+	$(hide) $(call copy-files-with-structure, $(CTS_SHARED_LIBS),$(HOST_OUT)/,$(PRIVATE_DIR))
 # Change mode of the executables
 	$(foreach jar,$(CTS_TEST_JAR_LIST),$(call copy-testcase-jar,$(jar)))
 	$(foreach testcase,$(CTS_TEST_CASES),$(call copy-testcase,$(testcase)))
diff --git a/core/tasks/deps_licenses.mk b/core/tasks/deps_licenses.mk
new file mode 100644
index 0000000..bb20fa0
--- /dev/null
+++ b/core/tasks/deps_licenses.mk
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2015 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.
+#
+
+# Print modules and their transitive dependencies with license files.
+# To invoke, run "make deps-license PROJ_PATH=<proj-path-patterns> DEP_PATH=<dep-path-patterns>".
+# PROJ_PATH restricts the paths of the source modules; DEP_PATH restricts the paths of the dependency modules.
+# Both can be makefile patterns supported by makefile function $(filter).
+# Example: "make deps-license packages/app/% external/%" prints all modules in packages/app/ with their dpendencies in external/.
+# The printout lines look like "<module_name> :: <module_paths> :: <license_files>".
+
+ifneq (,$(filter deps-license,$(MAKECMDGOALS)))
+ifndef PROJ_PATH
+$(error To "make deps-license" you must specify PROJ_PATH and DEP_PATH.)
+endif
+ifndef DEP_PATH
+$(error To "make deps-license" you must specify PROJ_PATH and DEP_PATH.)
+endif
+
+# Expand a module's dependencies transitively.
+# $(1): the variable name to hold the result.
+# $(2): the initial module name.
+define get-module-all-dependencies
+$(eval _gmad_new := $(sort $(filter-out $($(1)),\
+  $(foreach m,$(2),$(ALL_DEPS.$(m).ALL_DEPS)))))\
+$(if $(_gmad_new),$(eval $(1) += $(_gmad_new))\
+  $(call get-module-all-dependencies,$(1),$(_gmad_new)))
+endef
+
+define print-deps-license
+$(foreach m, $(ALL_DEPS.MODULES),\
+  $(eval m_p := $(sort $(ALL_MODULES.$(m).PATH) $(ALL_MODULES.$(m)$(TARGET_2ND_ARCH_MODULE_SUFFIX).PATH)))\
+  $(if $(filter $(PROJ_PATH),$(m_p)),\
+    $(eval deps :=)\
+    $(eval $(call get-module-all-dependencies,deps,$(m)))\
+    $(info $(m) :: $(m_p) :: $(ALL_DEPS.$(m).LICENSE))\
+    $(foreach d,$(deps),\
+      $(eval d_p := $(sort $(ALL_MODULES.$(d).PATH) $(ALL_MODULES.$(d)$(TARGET_2ND_ARCH_MODULE_SUFFIX).PATH)))\
+      $(if $(filter $(DEP_PATH),$(d_p)),\
+        $(info $(space)$(space)$(space)$(space)$(d) :: $(d_p) :: $(ALL_DEPS.$(d).LICENSE))))))
+endef
+
+.PHONY: deps-license
+deps-license:
+	@$(call print-deps-license)
+
+endif
diff --git a/target/board/generic_arm64/BoardConfig.mk b/target/board/generic_arm64/BoardConfig.mk
index c98624d..4b6136d 100644
--- a/target/board/generic_arm64/BoardConfig.mk
+++ b/target/board/generic_arm64/BoardConfig.mk
@@ -82,3 +82,5 @@
 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_FLASH_BLOCK_SIZE := 512
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
+
+BOARD_SEPOLICY_DIRS += build/target/board/generic/sepolicy
diff --git a/target/board/generic_mips64/BoardConfig.mk b/target/board/generic_mips64/BoardConfig.mk
index 7fe6cd3..8e8a68b 100644
--- a/target/board/generic_mips64/BoardConfig.mk
+++ b/target/board/generic_mips64/BoardConfig.mk
@@ -66,8 +66,12 @@
 
 TARGET_USERIMAGES_USE_EXT4 := true
 BOARD_SYSTEMIMAGE_PARTITION_SIZE := 1342177280  # 1.25 GB swag, 20% more than before
-BOARD_USERDATAIMAGE_PARTITION_SIZE := 734003200
+BOARD_USERDATAIMAGE_PARTITION_SIZE := 1610612736  # 1.5 GB, lots of space for running tests
 BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_FLASH_BLOCK_SIZE := 512
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
+
+BOARD_SEPOLICY_DIRS += build/target/board/generic/sepolicy
+
+DEX_PREOPT_DEFAULT := nostripping
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
index 295ee2b..62753a2 100755
--- a/target/board/generic_x86_64/BoardConfig.mk
+++ b/target/board/generic_x86_64/BoardConfig.mk
@@ -47,3 +47,7 @@
 BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_FLASH_BLOCK_SIZE := 512
 TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
+
+BOARD_SEPOLICY_DIRS += \
+        build/target/board/generic/sepolicy \
+        build/target/board/generic_x86/sepolicy
diff --git a/target/product/core_base.mk b/target/product/core_base.mk
index 6c29482..03d33e1 100644
--- a/target/product/core_base.mk
+++ b/target/product/core_base.mk
@@ -41,13 +41,14 @@
     libstagefright_soft_amrdec \
     libstagefright_soft_amrnbenc \
     libstagefright_soft_amrwbenc \
+    libstagefright_soft_avcdec \
+    libstagefright_soft_avcenc \
     libstagefright_soft_flacenc \
     libstagefright_soft_g711dec \
     libstagefright_soft_gsmdec \
-    libstagefright_soft_h264dec \
-    libstagefright_soft_h264enc \
     libstagefright_soft_hevcdec \
     libstagefright_soft_mp3dec \
+    libstagefright_soft_mpeg2dec \
     libstagefright_soft_mpeg4dec \
     libstagefright_soft_mpeg4enc \
     libstagefright_soft_opusdec \
diff --git a/target/product/embedded.mk b/target/product/embedded.mk
index 96c0b77..f0d74df 100644
--- a/target/product/embedded.mk
+++ b/target/product/embedded.mk
@@ -25,6 +25,7 @@
     debuggerd \
     dumpstate \
     dumpsys \
+    fastboot \
     gralloc.default \
     grep \
     gzip \
@@ -51,7 +52,6 @@
     libpower \
     libsigchain \
     libstdc++ \
-    libstlport \
     libsurfaceflinger \
     libsurfaceflinger_ddmconnection \
     libsysutils \
diff --git a/tools/droiddoc/templates-sac/head_tag.cs b/tools/droiddoc/templates-sac/head_tag.cs
index 9fca488..5cee68c 100644
--- a/tools/droiddoc/templates-sac/head_tag.cs
+++ b/tools/droiddoc/templates-sac/head_tag.cs
@@ -7,7 +7,7 @@
 <title><?cs 
   if:page.title ?><?cs 
     var:page.title ?> | <?cs
-  /if ?>Android Developers</title>
+  /if ?>Android Open Source Project</title>
 
 <!-- STYLESHEETS -->
 <link rel="stylesheet"
diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk
index f4c871a..34a3522 100644
--- a/tools/fs_config/Android.mk
+++ b/tools/fs_config/Android.mk
@@ -13,12 +13,73 @@
 # limitations under the License.
 
 LOCAL_PATH := $(call my-dir)
+
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := fs_config.c
 LOCAL_MODULE := fs_config
-LOCAL_STATIC_LIBRARIES := libcutils liblog libselinux
-LOCAL_FORCE_STATIC_EXECUTABLE := true
+LOCAL_SHARED_LIBRARIES := libcutils libselinux
 LOCAL_CFLAGS := -Werror
 
 include $(BUILD_HOST_EXECUTABLE)
+
+# To Build the custom target binary for the host to generate the fs_config
+# override files. The executable is hard coded to include the
+# $(TARGET_ANDROID_FILESYSTEM_CONFIG_H) file if it exists.
+# Expectations:
+#    device/<vendor>/<device>/android_filesystem_config.h
+#        fills in struct fs_path_config android_device_dirs[] and
+#                 struct fs_path_config android_device_files[]
+#    device/<vendor>/<device>/device.mk
+#        PRODUCT_PACKAGES += fs_config_dirs fs_config_files
+
+# If not specified, check if default one to be found
+ANDROID_FS_CONFIG_H := android_filesystem_config.h
+
+ifneq ($(TARGET_ANDROID_FILESYSTEM_CONFIG_H),)
+ifeq ($(filter %/$(ANDROID_FS_CONFIG_H),$(TARGET_ANDROID_FILESYSTEM_CONFIG_H)),)
+$(error TARGET_ANDROID_FILESYSTEM_CONFIG_H file name must be $(ANDROID_FS_CONFIG_H), \
+ see "$(notdir $(TARGET_ANDROID_FILESYSTEM_CONFIG_H))".)
+endif
+
+my_fs_config_h := $(TARGET_ANDROID_FILESYSTEM_CONFIG_H)
+else ifneq ($(wildcard $(TARGET_DEVICE_DIR)/$(ANDROID_FS_CONFIG_H)),)
+my_fs_config_h := $(TARGET_DEVICE_DIR)/$(ANDROID_FS_CONFIG_H)
+else
+my_fs_config_h := $(LOCAL_PATH)/default/$(ANDROID_FS_CONFIG_H)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := fs_config_generate.c
+LOCAL_MODULE := fs_config_generate_$(TARGET_DEVICE)
+LOCAL_SHARED_LIBRARIES := libcutils
+LOCAL_CFLAGS := -Werror -Wno-error=\#warnings
+LOCAL_C_INCLUDES := $(dir $(my_fs_config_h))
+include $(BUILD_HOST_EXECUTABLE)
+fs_config_generate_bin := $(LOCAL_INSTALLED_MODULE)
+
+# Generate the system/etc/fs_config_dirs binary file for the target
+# Add fs_config_dirs to PRODUCT_PACKAGES in the device make file to enable
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_dirs
+LOCAL_MODULE_CLASS := ETC
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE): $(fs_config_generate_bin)
+	@mkdir -p $(dir $@)
+	$< -D -o $@
+
+# Generate the system/etc/fs_config_files binary file for the target
+# Add fs_config_files to PRODUCT_PACKAGES in the device make file to enable
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_files
+LOCAL_MODULE_CLASS := ETC
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE): $(fs_config_generate_bin)
+	@mkdir -p $(dir $@)
+	$< -F -o $@
+
+ANDROID_FS_CONFIG_H :=
+my_fs_config_h :=
+fs_config_generate_bin :=
diff --git a/tools/fs_config/default/android_filesystem_config.h b/tools/fs_config/default/android_filesystem_config.h
new file mode 100644
index 0000000..820b04a
--- /dev/null
+++ b/tools/fs_config/default/android_filesystem_config.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+/* This file is used to enhance the properties of the filesystem
+** images generated by build tools (mkbootfs and mkyaffs2image) and
+** by the device side of adb.
+*/
+
+/*
+** Resorting to the default file means someone requested fs_config_dirs or
+** fs_config_files in their device configuration without providing an
+** associated header.
+*/
+#warning No device-supplied android_filesystem_config.h, using empty default.
+
+/* Rules for directories.
+** These rules are applied based on "first match", so they
+** should start with the most specific path and work their
+** way up to the root.
+*/
+
+#define NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS 1 /* opt out of specifying */
+
+/* Rules for files.
+** These rules are applied based on "first match", so they
+** should start with the most specific path and work their
+** way up to the root. Prefixes ending in * denotes wildcard
+** and will allow partial matches.
+*/
+
+#define NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES 1 /* opt out of specifying */
diff --git a/tools/fs_config/fs_config_generate.c b/tools/fs_config/fs_config_generate.c
new file mode 100644
index 0000000..c06213f
--- /dev/null
+++ b/tools/fs_config/fs_config_generate.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2015 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 <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <private/android_filesystem_config.h>
+
+/*
+ * This program expects android_device_dirs and android_device_files
+ * to be defined in the supplied android_filesystem_config.h file in
+ * the device/<vendor>/<product> $(TARGET_DEVICE_DIR). Then generates
+ * the binary format used in the /system/etc/fs_config_dirs and
+ * the /system/etc/fs_config_files to be used by the runtimes.
+ */
+#include "android_filesystem_config.h"
+
+#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+  static const struct fs_path_config android_device_dirs[] = {
+};
+#endif
+
+#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES
+static const struct fs_path_config android_device_files[] = {
+#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+    { 0, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_dirs" },
+#endif
+    { 0, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_files" },
+};
+#endif
+
+static void usage() {
+  fprintf(stderr,
+    "Generate binary content for fs_config_dirs (-D) and fs_config_files (-F)\n"
+    "from device-specific android_filesystem_config.h override\n\n"
+    "Usage: fs_config_generate -D|-F [-o output-file]\n");
+}
+
+int main(int argc, char** argv) {
+  const struct fs_path_config *pc;
+  const struct fs_path_config *end;
+  bool dir = false, file = false;
+  FILE *fp = stdout;
+  int opt;
+
+  while((opt = getopt(argc, argv, "DFho:")) != -1) {
+    switch(opt) {
+    case 'D':
+      if (file) {
+        fprintf(stderr, "Must specify only -D or -F\n");
+        usage();
+        exit(EXIT_FAILURE);
+      }
+      dir = true;
+      break;
+    case 'F':
+      if (dir) {
+        fprintf(stderr, "Must specify only -F or -D\n");
+        usage();
+        exit(EXIT_FAILURE);
+      }
+      file = true;
+      break;
+    case 'o':
+      if (fp != stdout) {
+        fprintf(stderr, "Specify only one output file\n");
+        usage();
+        exit(EXIT_FAILURE);
+      }
+      fp = fopen(optarg, "wb");
+      if (fp == NULL) {
+        fprintf(stderr, "Can not open \"%s\"\n", optarg);
+        exit(EXIT_FAILURE);
+      }
+      break;
+    case 'h':
+      usage();
+      exit(EXIT_SUCCESS);
+    default:
+      usage();
+      exit(EXIT_FAILURE);
+    }
+  }
+
+  if (!file && !dir) {
+    fprintf(stderr, "Must specify either -F or -D\n");
+    usage();
+    exit(EXIT_FAILURE);
+  }
+
+  if (dir) {
+    pc = android_device_dirs;
+    end = &android_device_dirs[sizeof(android_device_dirs) / sizeof(android_device_dirs[0])];
+  } else {
+    pc = android_device_files;
+    end = &android_device_files[sizeof(android_device_files) / sizeof(android_device_files[0])];
+  }
+  for(; (pc < end) && pc->prefix; pc++) {
+    char buffer[512];
+    ssize_t len = fs_config_generate(buffer, sizeof(buffer), pc);
+    if (len < 0) {
+      fprintf(stderr, "Entry too large\n");
+      exit(EXIT_FAILURE);
+    }
+    if (fwrite(buffer, 1, len, fp) != (size_t)len) {
+      fprintf(stderr, "Write failure\n");
+      exit(EXIT_FAILURE);
+    }
+  }
+  fclose(fp);
+
+  return 0;
+}
diff --git a/tools/java-event-log-tags.py b/tools/java-event-log-tags.py
index 846d9cf..f364751 100755
--- a/tools/java-event-log-tags.py
+++ b/tools/java-event-log-tags.py
@@ -129,7 +129,7 @@
     out += "_"
   return out
 
-javaTypes = ["ERROR", "int", "long", "String", "Object[]"]
+javaTypes = ["ERROR", "int", "long", "String", "Object[]", "float"]
 for t in tagfile.tags:
   methodName = javaName("write_" + t.tagname)
   if t.description:
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 7984ad6..eab8113 100755
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -33,10 +33,6 @@
 import tempfile
 import zipfile
 
-# missing in Python 2.4 and before
-if not hasattr(os, "SEEK_SET"):
-  os.SEEK_SET = 0
-
 import build_image
 import common
 
@@ -189,7 +185,7 @@
   assert succ, "build userdata.img image failed"
 
   common.CheckSize(img.name, "userdata.img", OPTIONS.info_dict)
-  output_zip.write(img.name, prefix + "userdata.img")
+  common.ZipWrite(output_zip, img.name, prefix + "userdata.img")
   img.close()
   os.rmdir(user_dir)
   os.rmdir(temp_dir)
@@ -226,7 +222,7 @@
   assert succ, "build cache.img image failed"
 
   common.CheckSize(img.name, "cache.img", OPTIONS.info_dict)
-  output_zip.write(img.name, prefix + "cache.img")
+  common.ZipWrite(output_zip, img.name, prefix + "cache.img")
   img.close()
   os.rmdir(user_dir)
   os.rmdir(temp_dir)
@@ -252,7 +248,7 @@
     OPTIONS.info_dict["selinux_fc"] = os.path.join(
         OPTIONS.input_tmp, "BOOT", "RAMDISK", "file_contexts")
 
-  input_zip.close()
+  common.ZipClose(input_zip)
   output_zip = zipfile.ZipFile(filename, "a",
                                compression=zipfile.ZIP_DEFLATED)
 
@@ -297,7 +293,7 @@
   banner("cache")
   AddCache(output_zip)
 
-  output_zip.close()
+  common.ZipClose(output_zip)
 
 def main(argv):
   def option_handler(o, _):
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index 75379cd..8eb249a 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -396,6 +396,12 @@
                 xf.style,
                 xf.tgt_ranges.to_string_raw(), src_str))
           elif self.version >= 3:
+            # take into account automatic stashing of overlapping blocks
+            if xf.src_ranges.overlaps(xf.tgt_ranges):
+              temp_stash_usage = stashed_blocks + xf.src_ranges.size();
+              if temp_stash_usage > max_stashed_blocks:
+                max_stashed_blocks = temp_stash_usage
+
             out.append("%s %s %s %s\n" % (
                 xf.style,
                 self.HashBlocks(self.tgt, xf.tgt_ranges),
@@ -414,6 +420,12 @@
               xf.style, xf.patch_start, xf.patch_len,
               xf.tgt_ranges.to_string_raw(), src_str))
         elif self.version >= 3:
+          # take into account automatic stashing of overlapping blocks
+          if xf.src_ranges.overlaps(xf.tgt_ranges):
+            temp_stash_usage = stashed_blocks + xf.src_ranges.size();
+            if temp_stash_usage > max_stashed_blocks:
+              max_stashed_blocks = temp_stash_usage
+
           out.append("%s %d %d %s %s %s %s\n" % (
               xf.style,
               xf.patch_start, xf.patch_len,
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 9f8a8ec..3909b4c 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -205,8 +205,8 @@
   Returns:
     True iff the image is built successfully.
   """
-  # system_root_image=true: build a system.img that combines the contents of /system
-  # and the ramdisk, and can be mounted at the root of the file system.
+  # system_root_image=true: build a system.img that combines the contents of
+  # /system and the ramdisk, and can be mounted at the root of the file system.
   origin_in = in_dir
   fs_config = prop_dict.get("fs_config")
   if (prop_dict.get("system_root_image") == "true"
@@ -375,8 +375,8 @@
     copy_prop("system_size", "partition_size")
     copy_prop("system_journal_size", "journal_size")
     copy_prop("system_verity_block_device", "verity_block_device")
-    copy_prop("system_root_image","system_root_image")
-    copy_prop("ramdisk_dir","ramdisk_dir")
+    copy_prop("system_root_image", "system_root_image")
+    copy_prop("ramdisk_dir", "ramdisk_dir")
   elif mount_point == "data":
     # Copy the generic fs type first, override with specific one if available.
     copy_prop("fs_type", "fs_type")
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 6a5d22f..227dcb8 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -32,10 +32,7 @@
 import blockimgdiff
 import rangelib
 
-try:
-  from hashlib import sha1 as sha1
-except ImportError:
-  from sha import sha as sha1
+from hashlib import sha1 as sha1
 
 
 class Options(object):
@@ -380,6 +377,10 @@
     p.communicate()
     assert p.returncode == 0, "vboot_signer of %s image failed" % path
 
+    # Clean up the temp files.
+    img_unsigned.close()
+    img_keyblock.close()
+
   img.seek(os.SEEK_SET, 0)
   data = img.read()
 
@@ -854,16 +855,50 @@
     zipfile.ZIP64_LIMIT = saved_zip64_limit
 
 
-def ZipWriteStr(zip_file, filename, data, perms=0o644, compression=None):
-  # use a fixed timestamp so the output is repeatable.
-  zinfo = zipfile.ZipInfo(filename=filename,
-                          date_time=(2009, 1, 1, 0, 0, 0))
-  if compression is None:
+def ZipWriteStr(zip_file, zinfo_or_arcname, data, perms=0o644,
+                compress_type=None):
+  """Wrap zipfile.writestr() function to work around the zip64 limit.
+
+  Even with the ZIP64_LIMIT workaround, it won't allow writing a string
+  longer than 2GiB. It gives 'OverflowError: size does not fit in an int'
+  when calling crc32(bytes).
+
+  But it still works fine to write a shorter string into a large zip file.
+  We should use ZipWrite() whenever possible, and only use ZipWriteStr()
+  when we know the string won't be too long.
+  """
+
+  saved_zip64_limit = zipfile.ZIP64_LIMIT
+  zipfile.ZIP64_LIMIT = (1 << 32) - 1
+
+  if not isinstance(zinfo_or_arcname, zipfile.ZipInfo):
+    zinfo = zipfile.ZipInfo(filename=zinfo_or_arcname)
     zinfo.compress_type = zip_file.compression
   else:
-    zinfo.compress_type = compression
+    zinfo = zinfo_or_arcname
+
+  # If compress_type is given, it overrides the value in zinfo.
+  if compress_type is not None:
+    zinfo.compress_type = compress_type
+
+  # Use a fixed timestamp so the output is repeatable.
   zinfo.external_attr = perms << 16
+  zinfo.date_time = (2009, 1, 1, 0, 0, 0)
+
   zip_file.writestr(zinfo, data)
+  zipfile.ZIP64_LIMIT = saved_zip64_limit
+
+
+def ZipClose(zip_file):
+  # http://b/18015246
+  # zipfile also refers to ZIP64_LIMIT during close() when it writes out the
+  # central directory.
+  saved_zip64_limit = zipfile.ZIP64_LIMIT
+  zipfile.ZIP64_LIMIT = (1 << 32) - 1
+
+  zip_file.close()
+
+  zipfile.ZIP64_LIMIT = saved_zip64_limit
 
 
 class DeviceSpecificParams(object):
@@ -969,7 +1004,7 @@
     return t
 
   def AddToZip(self, z, compression=None):
-    ZipWriteStr(z, self.name, self.data, compression=compression)
+    ZipWriteStr(z, self.name, self.data, compress_type=compression)
 
 DIFF_PROGRAM_BY_EXT = {
     ".gz" : "imgdiff",
@@ -1140,10 +1175,13 @@
       script.Print("Image %s will be patched unconditionally." % (partition,))
     else:
       if self.version >= 3:
-        script.AppendExtra(('if block_image_verify("%s", '
+        script.AppendExtra(('if (range_sha1("%s", "%s") == "%s" || '
+                            'block_image_verify("%s", '
                             'package_extract_file("%s.transfer.list"), '
-                            '"%s.new.dat", "%s.patch.dat") then') %
-                           (self.device, partition, partition, partition))
+                            '"%s.new.dat", "%s.patch.dat")) then') % (
+                            self.device, self.src.care_map.to_string_raw(),
+                            self.src.TotalSha1(),
+                            self.device, partition, partition, partition))
       else:
         script.AppendExtra('if range_sha1("%s", "%s") == "%s" then' % (
             self.device, self.src.care_map.to_string_raw(),
@@ -1214,7 +1252,8 @@
     "mtd": "MTD",
     "ext4": "EMMC",
     "emmc": "EMMC",
-    "f2fs": "EMMC"
+    "f2fs": "EMMC",
+    "squashfs": "EMMC"
 }
 
 def GetTypeAndDevice(mount_point, info):
diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py
index 8c5acd8..c486992 100755
--- a/tools/releasetools/img_from_target_files.py
+++ b/tools/releasetools/img_from_target_files.py
@@ -43,8 +43,9 @@
 
 def CopyInfo(output_zip):
   """Copy the android-info.txt file from the input to the output."""
-  output_zip.write(os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
-                   "android-info.txt")
+  common.ZipWrite(
+      output_zip, os.path.join(OPTIONS.input_tmp, "OTA", "android-info.txt"),
+      "android-info.txt")
 
 
 def main(argv):
@@ -133,13 +134,7 @@
 
   finally:
     print "cleaning up..."
-    # http://b/18015246
-    # See common.py for context.  zipfile also refers to ZIP64_LIMIT during
-    # close() when it writes out the central directory.
-    saved_zip64_limit = zipfile.ZIP64_LIMIT
-    zipfile.ZIP64_LIMIT = (1 << 32) - 1
-    output_zip.close()
-    zipfile.ZIP64_LIMIT = saved_zip64_limit
+    common.ZipClose(output_zip)
     shutil.rmtree(OPTIONS.input_tmp)
 
   print "done."
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 26fbaf0..900eaec 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -37,6 +37,11 @@
       Generate an incremental OTA using the given target-files zip as
       the starting build.
 
+  --full_radio
+      When generating an incremental OTA, always include a full copy of
+      radio image. This option is only meaningful when -i is specified,
+      because a full radio is always included in a full OTA if applicable.
+
   -v  (--verify)
       Remount and verify the checksums of the files written to the
       system and vendor (if used) partitions.  Incremental builds only.
@@ -87,7 +92,6 @@
   print >> sys.stderr, "Python 2.7 or newer is required."
   sys.exit(1)
 
-import copy
 import multiprocessing
 import os
 import tempfile
@@ -117,6 +121,7 @@
 OPTIONS.updater_binary = None
 OPTIONS.oem_source = None
 OPTIONS.fallback_to_full = True
+OPTIONS.full_radio = False
 
 def MostPopularKey(d, default):
   """Given a dict, return the key corresponding to the largest
@@ -365,6 +370,7 @@
         symlinks.append((input_zip.read(info.filename),
                          "/" + partition + "/" + basefilename))
       else:
+        import copy
         info2 = copy.copy(info)
         fn = info2.filename = partition + "/" + basefilename
         if substitute and fn in substitute and substitute[fn] is None:
@@ -374,7 +380,7 @@
             data = substitute[fn]
           else:
             data = input_zip.read(info.filename)
-          output_zip.writestr(info2, data)
+          common.ZipWriteStr(output_zip, info2, data)
         if fn.endswith("/"):
           itemset.Get(fn[:-1], is_dir=True)
         else:
@@ -556,6 +562,10 @@
 else if get_stage("%(bcb_dev)s") == "3/3" then
 """ % bcb_dev)
 
+  # Dump fingerprints
+  script.Print("Target: %s" % CalculateFingerprint(
+      oem_props, oem_dict, OPTIONS.info_dict))
+
   device_specific.FullOTA_InstallBegin()
 
   system_progress = 0.75
@@ -731,6 +741,12 @@
       metadata=metadata,
       info_dict=OPTIONS.info_dict)
 
+  # TODO: Currently this works differently from WriteIncrementalOTAPackage().
+  # This function doesn't consider thumbprints when writing
+  # metadata["pre/post-build"]. One possible reason is that the current
+  # devices with thumbprints are all using file-based OTAs. Long term we
+  # should factor out the common parts into a shared one to avoid further
+  # divergence.
   source_fp = GetBuildProp("ro.build.fingerprint", OPTIONS.source_info_dict)
   target_fp = GetBuildProp("ro.build.fingerprint", OPTIONS.target_info_dict)
   metadata["pre-build"] = source_fp
@@ -828,6 +844,12 @@
 else if get_stage("%(bcb_dev)s") != "3/3" then
 """ % bcb_dev)
 
+  # Dump fingerprints
+  script.Print("Source: %s" % CalculateFingerprint(
+      oem_props, oem_dict, OPTIONS.source_info_dict))
+  script.Print("Target: %s" % CalculateFingerprint(
+      oem_props, oem_dict, OPTIONS.target_info_dict))
+
   script.Print("Verifying current system...")
 
   device_specific.IncrementalOTA_VerifyBegin()
@@ -1206,6 +1228,10 @@
 else if get_stage("%(bcb_dev)s") != "3/3" then
 """ % bcb_dev)
 
+  # Dump fingerprints
+  script.Print("Source: %s" % (source_fp,))
+  script.Print("Target: %s" % (target_fp,))
+
   script.Print("Verifying current system...")
 
   device_specific.IncrementalOTA_VerifyBegin()
@@ -1436,6 +1462,8 @@
       OPTIONS.package_key = a
     elif o in ("-i", "--incremental_from"):
       OPTIONS.incremental_source = a
+    elif o == "--full_radio":
+      OPTIONS.full_radio = True
     elif o in ("-w", "--wipe_user_data"):
       OPTIONS.wipe_user_data = True
     elif o in ("-n", "--no_prereq"):
@@ -1477,6 +1505,7 @@
                                  "board_config=",
                                  "package_key=",
                                  "incremental_from=",
+                                 "full_radio",
                                  "wipe_user_data",
                                  "no_prereq",
                                  "extra_script=",
@@ -1552,6 +1581,7 @@
         OPTIONS.package_key = OPTIONS.info_dict.get(
             "default_system_dev_certificate",
             "build/target/product/security/testkey")
+      common.ZipClose(output_zip)
       break
 
     else:
@@ -1572,15 +1602,14 @@
         common.DumpInfoDict(OPTIONS.source_info_dict)
       try:
         WriteIncrementalOTAPackage(input_zip, source_zip, output_zip)
+        common.ZipClose(output_zip)
         break
       except ValueError:
         if not OPTIONS.fallback_to_full:
           raise
         print "--- failed to build incremental; falling back to full ---"
         OPTIONS.incremental_source = None
-        output_zip.close()
-
-  output_zip.close()
+        common.ZipClose(output_zip)
 
   if not OPTIONS.no_signing:
     SignOutput(temp_zip_file.name, args[1])
diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py
index d47cc4f..ec49112 100755
--- a/tools/releasetools/sign_target_files_apks.py
+++ b/tools/releasetools/sign_target_files_apks.py
@@ -196,23 +196,23 @@
       if key not in common.SPECIAL_CERT_STRINGS:
         print "    signing: %-*s (%s)" % (maxsize, name, key)
         signed_data = SignApk(data, key, key_passwords[key])
-        output_tf_zip.writestr(out_info, signed_data)
+        common.ZipWriteStr(output_tf_zip, out_info, signed_data)
       else:
         # an APK we're not supposed to sign.
         print "NOT signing: %s" % (name,)
-        output_tf_zip.writestr(out_info, data)
+        common.ZipWriteStr(output_tf_zip, out_info, data)
     elif info.filename in ("SYSTEM/build.prop",
                            "VENDOR/build.prop",
                            "RECOVERY/RAMDISK/default.prop"):
       print "rewriting %s:" % (info.filename,)
       new_data = RewriteProps(data, misc_info)
-      output_tf_zip.writestr(out_info, new_data)
+      common.ZipWriteStr(output_tf_zip, out_info, new_data)
       if info.filename == "RECOVERY/RAMDISK/default.prop":
         write_to_temp(info.filename, info.external_attr, new_data)
     elif info.filename.endswith("mac_permissions.xml"):
       print "rewriting %s with new keys." % (info.filename,)
       new_data = ReplaceCerts(data)
-      output_tf_zip.writestr(out_info, new_data)
+      common.ZipWriteStr(output_tf_zip, out_info, new_data)
     elif info.filename in ("SYSTEM/recovery-from-boot.p",
                            "SYSTEM/bin/install-recovery.sh"):
       rebuild_recovery = True
@@ -229,7 +229,7 @@
       pass
     else:
       # a non-APK file; copy it verbatim
-      output_tf_zip.writestr(out_info, data)
+      common.ZipWriteStr(output_tf_zip, out_info, data)
 
   if OPTIONS.replace_ota_keys:
     new_recovery_keys = ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info)
@@ -243,7 +243,7 @@
         "boot.img", "boot.img", tmpdir, "BOOT", info_dict=misc_info)
 
     def output_sink(fn, data):
-      output_tf_zip.writestr("SYSTEM/"+fn, data)
+      common.ZipWriteStr(output_tf_zip, "SYSTEM/" + fn, data)
 
     common.MakeRecoveryPatch(tmpdir, output_sink, recovery_img, boot_img,
                              info_dict=misc_info)
@@ -488,8 +488,8 @@
   ProcessTargetFiles(input_zip, output_zip, misc_info,
                      apk_key_map, key_passwords)
 
-  input_zip.close()
-  output_zip.close()
+  common.ZipClose(input_zip)
+  common.ZipClose(output_zip)
 
   add_img_to_target_files.AddImagesToTargetFiles(args[1])
 
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index 5fdc132..f28934d 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -29,15 +29,54 @@
     data[begin:end] = os.urandom(block_size)
   return "".join(data)
 
+def get_2gb_string():
+  kilobytes = 1024
+  megabytes = 1024 * kilobytes
+  gigabytes = 1024 * megabytes
+
+  size = int(2 * gigabytes + 1)
+  block_size = 4 * kilobytes
+  step_size = 4 * megabytes
+  two_gb_string = random_string_with_holes(
+        size, block_size, step_size)
+  return two_gb_string
+
 
 class CommonZipTest(unittest.TestCase):
+  def _verify(self, zip_file, zip_file_name, arcname, contents,
+              test_file_name=None, expected_stat=None, expected_mode=0o644,
+              expected_compress_type=zipfile.ZIP_STORED):
+    # Verify the stat if present.
+    if test_file_name is not None:
+      new_stat = os.stat(test_file_name)
+      self.assertEqual(int(expected_stat.st_mode), int(new_stat.st_mode))
+      self.assertEqual(int(expected_stat.st_mtime), int(new_stat.st_mtime))
+
+    # Reopen the zip file to verify.
+    zip_file = zipfile.ZipFile(zip_file_name, "r")
+
+    # Verify the timestamp.
+    info = zip_file.getinfo(arcname)
+    self.assertEqual(info.date_time, (2009, 1, 1, 0, 0, 0))
+
+    # Verify the file mode.
+    mode = (info.external_attr >> 16) & 0o777
+    self.assertEqual(mode, expected_mode)
+
+    # Verify the compress type.
+    self.assertEqual(info.compress_type, expected_compress_type)
+
+    # Verify the zip contents.
+    self.assertEqual(zip_file.read(arcname), contents)
+    self.assertIsNone(zip_file.testzip())
+
   def _test_ZipWrite(self, contents, extra_zipwrite_args=None):
     extra_zipwrite_args = dict(extra_zipwrite_args or {})
 
     test_file = tempfile.NamedTemporaryFile(delete=False)
-    zip_file = tempfile.NamedTemporaryFile(delete=False)
-
     test_file_name = test_file.name
+
+    zip_file = tempfile.NamedTemporaryFile(delete=False)
     zip_file_name = zip_file.name
 
     # File names within an archive strip the leading slash.
@@ -52,31 +91,100 @@
       test_file.write(contents)
       test_file.close()
 
-      old_stat = os.stat(test_file_name)
+      expected_stat = os.stat(test_file_name)
       expected_mode = extra_zipwrite_args.get("perms", 0o644)
-
+      expected_compress_type = extra_zipwrite_args.get("compress_type",
+                                                       zipfile.ZIP_STORED)
       time.sleep(5)  # Make sure the atime/mtime will change measurably.
 
       common.ZipWrite(zip_file, test_file_name, **extra_zipwrite_args)
+      common.ZipClose(zip_file)
 
-      new_stat = os.stat(test_file_name)
-      self.assertEqual(int(old_stat.st_mode), int(new_stat.st_mode))
-      self.assertEqual(int(old_stat.st_mtime), int(new_stat.st_mtime))
-      self.assertIsNone(zip_file.testzip())
-
-      zip_file.close()
-      zip_file = zipfile.ZipFile(zip_file_name, "r")
-      info = zip_file.getinfo(arcname)
-
-      self.assertEqual(info.date_time, (2009, 1, 1, 0, 0, 0))
-      mode = (info.external_attr >> 16) & 0o777
-      self.assertEqual(mode, expected_mode)
-      self.assertEqual(zip_file.read(arcname), contents)
-      self.assertIsNone(zip_file.testzip())
+      self._verify(zip_file, zip_file_name, arcname, contents, test_file_name,
+                   expected_stat, expected_mode, expected_compress_type)
     finally:
       os.remove(test_file_name)
       os.remove(zip_file_name)
 
+  def _test_ZipWriteStr(self, zinfo_or_arcname, contents, extra_args=None):
+    extra_args = dict(extra_args or {})
+
+    zip_file = tempfile.NamedTemporaryFile(delete=False)
+    zip_file_name = zip_file.name
+    zip_file.close()
+
+    zip_file = zipfile.ZipFile(zip_file_name, "w")
+
+    try:
+      expected_compress_type = extra_args.get("compress_type",
+                                              zipfile.ZIP_STORED)
+      time.sleep(5)  # Make sure the atime/mtime will change measurably.
+
+      if not isinstance(zinfo_or_arcname, zipfile.ZipInfo):
+        zinfo = zipfile.ZipInfo(filename=zinfo_or_arcname)
+      else:
+        zinfo = zinfo_or_arcname
+      arcname = zinfo.filename
+
+      common.ZipWriteStr(zip_file, zinfo, contents, **extra_args)
+      common.ZipClose(zip_file)
+
+      self._verify(zip_file, zip_file_name, arcname, contents,
+                   expected_compress_type=expected_compress_type)
+    finally:
+      os.remove(zip_file_name)
+
+  def _test_ZipWriteStr_large_file(self, large, small, extra_args=None):
+    extra_args = dict(extra_args or {})
+
+    zip_file = tempfile.NamedTemporaryFile(delete=False)
+    zip_file_name = zip_file.name
+
+    test_file = tempfile.NamedTemporaryFile(delete=False)
+    test_file_name = test_file.name
+
+    arcname_large = test_file_name
+    arcname_small = "bar"
+
+    # File names within an archive strip the leading slash.
+    if arcname_large[0] == "/":
+      arcname_large = arcname_large[1:]
+
+    zip_file.close()
+    zip_file = zipfile.ZipFile(zip_file_name, "w")
+
+    try:
+      test_file.write(large)
+      test_file.close()
+
+      expected_stat = os.stat(test_file_name)
+      expected_mode = 0o644
+      expected_compress_type = extra_args.get("compress_type",
+                                              zipfile.ZIP_STORED)
+      time.sleep(5)  # Make sure the atime/mtime will change measurably.
+
+      common.ZipWrite(zip_file, test_file_name, **extra_args)
+      common.ZipWriteStr(zip_file, arcname_small, small, **extra_args)
+      common.ZipClose(zip_file)
+
+      # Verify the contents written by ZipWrite().
+      self._verify(zip_file, zip_file_name, arcname_large, large,
+                   test_file_name, expected_stat, expected_mode,
+                   expected_compress_type)
+
+      # Verify the contents written by ZipWriteStr().
+      self._verify(zip_file, zip_file_name, arcname_small, small,
+                   expected_compress_type=expected_compress_type)
+    finally:
+      os.remove(zip_file_name)
+      os.remove(test_file_name)
+
+  def _test_reset_ZIP64_LIMIT(self, func, *args):
+    default_limit = (1 << 31) - 1
+    self.assertEqual(default_limit, zipfile.ZIP64_LIMIT)
+    func(*args)
+    self.assertEqual(default_limit, zipfile.ZIP64_LIMIT)
+
   def test_ZipWrite(self):
     file_contents = os.urandom(1024)
     self._test_ZipWrite(file_contents)
@@ -88,23 +196,64 @@
         "perms": 0o777,
         "compress_type": zipfile.ZIP_DEFLATED,
     })
+    self._test_ZipWrite(file_contents, {
+        "arcname": "foobar",
+        "perms": 0o700,
+        "compress_type": zipfile.ZIP_STORED,
+    })
 
   def test_ZipWrite_large_file(self):
-    kilobytes = 1024
-    megabytes = 1024 * kilobytes
-    gigabytes = 1024 * megabytes
-
-    size = int(2 * gigabytes + 1)
-    block_size = 4 * kilobytes
-    step_size = 4 * megabytes
-    file_contents = random_string_with_holes(
-        size, block_size, step_size)
+    file_contents = get_2gb_string()
     self._test_ZipWrite(file_contents, {
         "compress_type": zipfile.ZIP_DEFLATED,
     })
 
   def test_ZipWrite_resets_ZIP64_LIMIT(self):
-    default_limit = (1 << 31) - 1
-    self.assertEqual(default_limit, zipfile.ZIP64_LIMIT)
-    self._test_ZipWrite('')
-    self.assertEqual(default_limit, zipfile.ZIP64_LIMIT)
+    self._test_reset_ZIP64_LIMIT(self._test_ZipWrite, "")
+
+  def test_ZipWriteStr(self):
+    random_string = os.urandom(1024)
+    # Passing arcname
+    self._test_ZipWriteStr("foo", random_string)
+
+    # Passing zinfo
+    zinfo = zipfile.ZipInfo(filename="foo")
+    self._test_ZipWriteStr(zinfo, random_string)
+
+    # Timestamp in the zinfo should be overwritten.
+    zinfo.date_time = (2015, 3, 1, 15, 30, 0)
+    self._test_ZipWriteStr(zinfo, random_string)
+
+  def test_ZipWriteStr_with_opts(self):
+    random_string = os.urandom(1024)
+    # Passing arcname
+    self._test_ZipWriteStr("foo", random_string, {
+        "compress_type": zipfile.ZIP_DEFLATED,
+    })
+    self._test_ZipWriteStr("foo", random_string, {
+        "compress_type": zipfile.ZIP_STORED,
+    })
+
+    # Passing zinfo
+    zinfo = zipfile.ZipInfo(filename="foo")
+    self._test_ZipWriteStr(zinfo, random_string, {
+        "compress_type": zipfile.ZIP_DEFLATED,
+    })
+    self._test_ZipWriteStr(zinfo, random_string, {
+        "compress_type": zipfile.ZIP_STORED,
+    })
+
+  def test_ZipWriteStr_large_file(self):
+    # zipfile.writestr() doesn't work when the str size is over 2GiB even with
+    # the workaround. We will only test the case of writing a string into a
+    # large archive.
+    long_string = get_2gb_string()
+    short_string = os.urandom(1024)
+    self._test_ZipWriteStr_large_file(long_string, short_string, {
+        "compress_type": zipfile.ZIP_DEFLATED,
+    })
+
+  def test_ZipWriteStr_resets_ZIP64_LIMIT(self):
+    self._test_reset_ZIP64_LIMIT(self._test_ZipWriteStr, "foo", "")
+    zinfo = zipfile.ZipInfo(filename="foo")
+    self._test_reset_ZIP64_LIMIT(self._test_ZipWriteStr, zinfo, "")