Merge "Add LOCAL_SANITIZE_RECOVER."
diff --git a/core/binary.mk b/core/binary.mk
index 8eefa76..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.
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 3687d94..1357b39 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -92,8 +92,8 @@
 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_PREBUILT_JNI_LIBS:=
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..3651c39 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -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 07a1de9..0819d13 100644
--- a/core/combo/TARGET_linux-arm64.mk
+++ b/core/combo/TARGET_linux-arm64.mk
@@ -158,7 +158,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..29e49fb 100644
--- a/core/combo/TARGET_linux-mips.mk
+++ b/core/combo/TARGET_linux-mips.mk
@@ -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..b34b7a6 100644
--- a/core/combo/TARGET_linux-mips64.mk
+++ b/core/combo/TARGET_linux-mips64.mk
@@ -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..ed78372 100644
--- a/core/combo/TARGET_linux-x86.mk
+++ b/core/combo/TARGET_linux-x86.mk
@@ -142,7 +142,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..0b2905c 100644
--- a/core/combo/TARGET_linux-x86_64.mk
+++ b/core/combo/TARGET_linux-x86_64.mk
@@ -151,8 +151,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/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/definitions.mk b/core/definitions.mk
index 6114395..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
@@ -1944,6 +1953,16 @@
 $(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; \
diff --git a/core/dynamic_binary.mk b/core/dynamic_binary.mk
index cf06a3d..fe498ed 100644
--- a/core/dynamic_binary.mk
+++ b/core/dynamic_binary.mk
@@ -39,30 +39,6 @@
 ###################################
 
 ###########################################################
-## Compress
-###########################################################
-compress_input := $(linked_module)
-
-ifeq ($(strip $(LOCAL_COMPRESS_MODULE_SYMBOLS)),)
-  LOCAL_COMPRESS_MODULE_SYMBOLS := $(strip $(TARGET_COMPRESS_MODULE_SYMBOLS))
-endif
-
-ifeq ($(LOCAL_COMPRESS_MODULE_SYMBOLS),true)
-$(error Symbol compression not yet supported.)
-compress_output := $(intermediates)/COMPRESSED-$(my_built_module_stem)
-
-#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)
-else
-# Skip this step.
-compress_output := $(compress_input)
-endif
-
-###########################################################
 ## Store a copy with symbols for symbolic debugging
 ###########################################################
 ifeq ($(LOCAL_UNSTRIPPED_PATH),)
@@ -70,7 +46,7 @@
 else
 my_unstripped_path := $(LOCAL_UNSTRIPPED_PATH)
 endif
-symbolic_input := $(compress_output)
+symbolic_input := $(linked_module)
 symbolic_output := $(my_unstripped_path)/$(my_installed_module_stem)
 $(symbolic_output) : $(symbolic_input) | $(ACP)
 	@echo "target Symbolic: $(PRIVATE_MODULE) ($@)"
@@ -81,11 +57,11 @@
 ## Strip
 ###########################################################
 strip_input := $(symbolic_output)
-strip_output := $(LOCAL_BUILT_MODULE)
+strip_output := $(intermediates)/STRIPPED/$(my_built_module_stem)
 
 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 +107,39 @@
 endif
 endif # my_strip_module
 
+###########################################################
+## Pack relocation tables
+###########################################################
+relocation_packer_input := $(strip_output)
+relocation_packer_output := $(LOCAL_BUILT_MODULE)
+
+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
+
+# Do not pack relocations for static executables.
+ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
+  my_pack_module_relocations := false
+endif
+
+# 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
+$(relocation_packer_output): $(relocation_packer_input) | $(ACP)
+	@echo "target Unpacked: $(PRIVATE_MODULE) ($@)"
+	$(copy-file-to-target)
+endif
 
 $(cleantarget): PRIVATE_CLEAN_FILES += \
     $(linked_module) \
     $(symbolic_output) \
-    $(compress_output)
+    $(strip_output)
diff --git a/core/main.mk b/core/main.mk
index 13465e3..41e2801 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 :=
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 8595bce..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)
 
@@ -205,6 +210,9 @@
 endif
 	$(sign-package)
 endif
+ifeq ($(LOCAL_PAGE_ALIGN_JNI_SHARED_LIBRARIES),true)
+	$(uncompress-shared-libs)
+endif
 	$(align-package)
 
 ###############################
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/tools/releasetools/common.py b/tools/releasetools/common.py
index 6a5d22f..a8b0035 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1140,10 +1140,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(),
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 21565fc..eab3daa 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.
@@ -117,6 +122,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
@@ -1456,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"):
@@ -1497,6 +1505,7 @@
                                  "board_config=",
                                  "package_key=",
                                  "incremental_from=",
+                                 "full_radio",
                                  "wipe_user_data",
                                  "no_prereq",
                                  "extra_script=",