Merge "Remove HAVE_STDINT_H namespace pollution."
diff --git a/core/Makefile b/core/Makefile
index 92f1fb6..e17c4ed 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -701,6 +701,7 @@
 $(if $(BOARD_SYSTEMIMAGE_PARTITION_SIZE),$(hide) echo "system_size=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)" >> $(1))
 $(if $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "system_fs_type=$(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
 $(if $(BOARD_SYSTEMIMAGE_JOURNAL_SIZE),$(hide) echo "system_journal_size=$(BOARD_SYSTEMIMAGE_JOURNAL_SIZE)" >> $(1))
+$(if $(BOARD_HAS_EXT4_RESERVED_BLOCKS),$(hide) echo "has_ext4_reserved_blocks=$(BOARD_HAS_EXT4_RESERVED_BLOCKS)" >> $(1))
 $(if $(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "userdata_fs_type=$(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
 $(if $(BOARD_USERDATAIMAGE_PARTITION_SIZE),$(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(1))
 $(if $(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "cache_fs_type=$(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
@@ -965,7 +966,15 @@
       $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) \
       || ( echo "Out of space? the tree size of $(TARGET_OUT) is (MB): " 1>&2 ;\
            du -sm $(TARGET_OUT) 1>&2;\
-           echo "The max is $$(( $(BOARD_SYSTEMIMAGE_PARTITION_SIZE) / 1048576 )) MB." 1>&2 ;\
+           if [ "$(INTERNAL_USERIMAGES_EXT_VARIANT)" == "ext4" ]; then \
+               maxsize=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE); \
+               if [ "$(BOARD_HAS_EXT4_RESERVED_BLOCKS)" == "true" ]; then \
+                   maxsize=$$((maxsize - 4096 * 4096)); \
+               fi; \
+               echo "The max is $$(( maxsize / 1048576 )) MB." 1>&2 ;\
+           else \
+               echo "The max is $$(( $(BOARD_SYSTEMIMAGE_PARTITION_SIZE) / 1048576 )) MB." 1>&2 ;\
+           fi; \
            mkdir -p $(DIST_DIR); cp $(INSTALLED_FILES_FILE) $(DIST_DIR)/installed-files-rescued.txt; \
            exit 1 )
 endef
@@ -1456,6 +1465,9 @@
 ifdef BOARD_RECOVERYIMAGE_PARTITION_SIZE
 	$(hide) echo "recovery_size=$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
 endif
+ifdef BOARD_HAS_EXT4_RESERVED_BLOCKS
+	$(hide) echo "has_ext4_reserved_blocks=$(BOARD_HAS_EXT4_RESERVED_BLOCKS)" >> $(zip_root)/META/misc_info.txt
+endif
 ifdef TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS
 	@# TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS can be empty to indicate that nothing but defaults should be used.
 	$(hide) echo "recovery_mount_options=$(TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS)" >> $(zip_root)/META/misc_info.txt
diff --git a/core/clang/TARGET_arm.mk b/core/clang/TARGET_arm.mk
index 1b13098..cd25604 100644
--- a/core/clang/TARGET_arm.mk
+++ b/core/clang/TARGET_arm.mk
@@ -69,4 +69,4 @@
 
 # Address sanitizer clang config
 $(clang_2nd_arch_prefix)ADDRESS_SANITIZER_RUNTIME_LIBRARY := libclang_rt.asan-arm-android
-$(clang_2nd_arch_prefix)ADDRESS_SANITIZER_RPATH := /data/lib
+$(clang_2nd_arch_prefix)ADDRESS_SANITIZER_RPATH := /data/vendor/lib:/$(TARGET_COPY_OUT_VENDOR)/lib:/data/lib
diff --git a/core/clang/TARGET_arm64.mk b/core/clang/TARGET_arm64.mk
index 7900f93..0861568 100644
--- a/core/clang/TARGET_arm64.mk
+++ b/core/clang/TARGET_arm64.mk
@@ -67,4 +67,4 @@
 
 # Address sanitizer clang config
 ADDRESS_SANITIZER_RUNTIME_LIBRARY := libclang_rt.asan-arm64-android
-ADDRESS_SANITIZER_RPATH := /data/lib64
+ADDRESS_SANITIZER_RPATH := /data/vendor/lib64:/$(TARGET_COPY_OUT_VENDOR)/lib64:/data/lib64
diff --git a/core/clang/mips.mk b/core/clang/mips.mk
index 70832a3..4a8f812 100644
--- a/core/clang/mips.mk
+++ b/core/clang/mips.mk
@@ -12,6 +12,7 @@
   -frerun-cse-after-loop \
   -frename-registers \
   -msynci \
+  -mno-synci \
   -mno-fused-madd
 
 # Temporary workaround for Mips clang++ problem,  creates
diff --git a/core/clang/mips64.mk b/core/clang/mips64.mk
index ba9c1d1..1b72e05 100644
--- a/core/clang/mips64.mk
+++ b/core/clang/mips64.mk
@@ -12,6 +12,7 @@
   -frerun-cse-after-loop \
   -frename-registers \
   -msynci \
+  -mno-synci \
   -mno-fused-madd
 
 # Temporary workaround for Mips clang++ problem creating
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index f30c8ba..bd6902c 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -142,6 +142,7 @@
 LOCAL_PROTOC_FLAGS:=
 LOCAL_PROTO_JAVA_OUTPUT_PARAMS:=
 LOCAL_NO_CRT:=
+LOCAL_NO_LIBGCC:=
 LOCAL_PROPRIETARY_MODULE:=
 LOCAL_OEM_MODULE:=
 LOCAL_ODM_MODULE:=
diff --git a/core/combo/arch/mips/mips32-fp.mk b/core/combo/arch/mips/mips32-fp.mk
index 8320e93..912ff63 100644
--- a/core/combo/arch/mips/mips32-fp.mk
+++ b/core/combo/arch/mips/mips32-fp.mk
@@ -7,6 +7,7 @@
     -mips32 \
     -mfp32 \
     -modd-spreg \
+    -mno-synci
 
 arch_variant_ldflags := \
     -Wl,-melf32ltsmip
diff --git a/core/combo/arch/mips/mips32r2-fp-xburst.mk b/core/combo/arch/mips/mips32r2-fp-xburst.mk
index 2b4f714..09b3bc2 100644
--- a/core/combo/arch/mips/mips32r2-fp-xburst.mk
+++ b/core/combo/arch/mips/mips32r2-fp-xburst.mk
@@ -9,7 +9,8 @@
     -mfp32 \
     -modd-spreg \
     -mno-fused-madd \
-    -Wa,-mmxu
+    -Wa,-mmxu \
+    -mno-synci
 
 arch_variant_ldflags := \
     -Wl,-melf32ltsmip
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 688e6a4..962d269 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -332,12 +332,18 @@
 TARGET_OUT_CACHE := $(PRODUCT_OUT)/cache
 
 TARGET_OUT_VENDOR := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_VENDOR)
+ifeq ($(SANITIZE_TARGET),address)
+target_out_vendor_shared_libraries_base := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_DATA)/vendor
+else
+target_out_vendor_shared_libraries_base := $(TARGET_OUT_VENDOR)
+endif
+
 TARGET_OUT_VENDOR_EXECUTABLES := $(TARGET_OUT_VENDOR)/bin
 TARGET_OUT_VENDOR_OPTIONAL_EXECUTABLES := $(TARGET_OUT_VENDOR)/xbin
 ifeq ($(TARGET_IS_64_BIT),true)
-TARGET_OUT_VENDOR_SHARED_LIBRARIES := $(TARGET_OUT_VENDOR)/lib64
+TARGET_OUT_VENDOR_SHARED_LIBRARIES := $(target_out_vendor_shared_libraries_base)/lib64
 else
-TARGET_OUT_VENDOR_SHARED_LIBRARIES := $(TARGET_OUT_VENDOR)/lib
+TARGET_OUT_VENDOR_SHARED_LIBRARIES := $(target_out_vendor_shared_libraries_base)/lib
 endif
 TARGET_OUT_VENDOR_JAVA_LIBRARIES := $(TARGET_OUT_VENDOR)/framework
 TARGET_OUT_VENDOR_APPS := $(TARGET_OUT_VENDOR)/app
diff --git a/core/executable_internal.mk b/core/executable_internal.mk
index 2684d51..cdaf293 100644
--- a/core/executable_internal.mk
+++ b/core/executable_internal.mk
@@ -37,7 +37,11 @@
 my_target_global_ld_dirs := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_LD_DIRS)
 my_target_libprofile_rt := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBPROFILE_RT)
 my_target_libgcov := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBGCOV)
+ifeq ($(LOCAL_NO_LIBGCC),true)
+my_target_libgcc :=
+else
 my_target_libgcc := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBGCC)
+endif
 my_target_libatomic := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBATOMIC)
 my_target_crtbegin_dynamic_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_CRTBEGIN_DYNAMIC_O)
 my_target_crtbegin_static_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_CRTBEGIN_STATIC_O)
diff --git a/core/shared_library_internal.mk b/core/shared_library_internal.mk
index 2487fbb0..e21cf5d 100644
--- a/core/shared_library_internal.mk
+++ b/core/shared_library_internal.mk
@@ -42,7 +42,11 @@
 my_target_global_ld_dirs := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_LD_DIRS)
 my_target_libprofile_rt := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBPROFILE_RT)
 my_target_libgcov := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBGCOV)
+ifeq ($(LOCAL_NO_LIBGCC),true)
+my_target_libgcc :=
+else
 my_target_libgcc := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBGCC)
+endif
 my_target_libatomic := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_LIBATOMIC)
 my_target_crtbegin_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_CRTBEGIN_SO_O)
 my_target_crtend_so_o := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_CRTEND_SO_O)
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 594479e..8934c77 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -22,6 +22,7 @@
 """
 import os
 import os.path
+import re
 import subprocess
 import sys
 import commands
@@ -31,17 +32,18 @@
 FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
 
 def RunCommand(cmd):
-  """ Echo and run the given command.
+  """Echo and run the given command.
 
   Args:
     cmd: the command represented as a list of strings.
   Returns:
-    The exit code.
+    A tuple of the output and the exit code.
   """
   print "Running: ", " ".join(cmd)
-  p = subprocess.Popen(cmd)
-  p.communicate()
-  return p.returncode
+  p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+  output, _ = p.communicate()
+  print "%s" % (output.rstrip(),)
+  return (output, p.returncode)
 
 def GetVerityTreeSize(partition_size):
   cmd = "build_verity_tree -s %d"
@@ -142,7 +144,7 @@
     else:
       return True, unsparse_image_path
   inflate_command = ["simg2img", sparse_image_path, unsparse_image_path]
-  exit_code = RunCommand(inflate_command)
+  (_, exit_code) = RunCommand(inflate_command)
   if exit_code != 0:
     os.remove(unsparse_image_path)
     return False, None
@@ -233,11 +235,12 @@
 
   fs_spans_partition = True
   if fs_type.startswith("squash"):
-      fs_spans_partition = False
+    fs_spans_partition = False
 
   is_verity_partition = "verity_block_device" in prop_dict
   verity_supported = prop_dict.get("verity") == "true"
-  # adjust the partition size to make room for the hashes if this is to be verified
+  # Adjust the partition size to make room for the hashes if this is to be
+  # verified.
   if verity_supported and is_verity_partition and fs_spans_partition:
     partition_size = int(prop_dict.get("partition_size"))
     adjusted_size = AdjustPartitionSizeForVerity(partition_size)
@@ -294,8 +297,15 @@
     staging_system = os.path.join(in_dir, "system")
     shutil.rmtree(staging_system, ignore_errors=True)
     shutil.copytree(origin_in, staging_system, symlinks=True)
+
+  reserved_blocks = prop_dict.get("has_ext4_reserved_blocks") == "true"
+  ext4fs_output = None
+
   try:
-    exit_code = RunCommand(build_command)
+    if reserved_blocks and fs_type.startswith("ext4"):
+      (ext4fs_output, exit_code) = RunCommand(build_command)
+    else:
+      (_, exit_code) = RunCommand(build_command)
   finally:
     if in_dir != origin_in:
       # Clean up temporary directories and files.
@@ -305,17 +315,42 @@
   if exit_code != 0:
     return False
 
+  # Bug: 21522719, 22023465
+  # There are some reserved blocks on ext4 FS (lesser of 4096 blocks and 2%).
+  # We need to deduct those blocks from the available space, since they are
+  # not writable even with root privilege. It only affects devices using
+  # file-based OTA and a kernel version of 3.10 or greater (currently just
+  # sprout).
+  if reserved_blocks and fs_type.startswith("ext4"):
+    assert ext4fs_output is not None
+    ext4fs_stats = re.compile(
+        r'Created filesystem with .* (?P<used_blocks>[0-9]+)/'
+        r'(?P<total_blocks>[0-9]+) blocks')
+    m = ext4fs_stats.match(ext4fs_output.strip().split('\n')[-1])
+    used_blocks = int(m.groupdict().get('used_blocks'))
+    total_blocks = int(m.groupdict().get('total_blocks'))
+    reserved_blocks = min(4096, int(total_blocks * 0.02))
+    adjusted_blocks = total_blocks - reserved_blocks
+    if used_blocks > adjusted_blocks:
+      mount_point = prop_dict.get("mount_point")
+      print("Error: Not enough room on %s (total: %d blocks, used: %d blocks, "
+            "reserved: %d blocks, available: %d blocks)" % (
+                mount_point, total_blocks, used_blocks, reserved_blocks,
+                adjusted_blocks))
+      return False
+
   if not fs_spans_partition:
     mount_point = prop_dict.get("mount_point")
     partition_size = int(prop_dict.get("partition_size"))
     image_size = os.stat(out_file).st_size
     if image_size > partition_size:
-        print "Error: %s image size of %d is larger than partition size of %d" % (mount_point, image_size, partition_size)
-        return False
+      print("Error: %s image size of %d is larger than partition size of "
+            "%d" % (mount_point, image_size, partition_size))
+      return False
     if verity_supported and is_verity_partition:
-        if 2 * image_size - AdjustPartitionSizeForVerity(image_size) > partition_size:
-            print "Error: No more room on %s to fit verity data" % mount_point
-            return False
+      if 2 * image_size - AdjustPartitionSizeForVerity(image_size) > partition_size:
+        print "Error: No more room on %s to fit verity data" % mount_point
+        return False
     prop_dict["original_partition_size"] = prop_dict["partition_size"]
     prop_dict["partition_size"] = str(image_size)
 
@@ -331,7 +366,7 @@
 
     # Run e2fsck on the inflated image file
     e2fsck_command = ["e2fsck", "-f", "-n", unsparse_image]
-    exit_code = RunCommand(e2fsck_command)
+    (_, exit_code) = RunCommand(e2fsck_command)
 
     os.remove(unsparse_image)
 
@@ -378,6 +413,7 @@
     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("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
   elif mount_point == "data":
     # Copy the generic fs type first, override with specific one if available.
     copy_prop("fs_type", "fs_type")
@@ -391,10 +427,12 @@
     copy_prop("vendor_size", "partition_size")
     copy_prop("vendor_journal_size", "journal_size")
     copy_prop("vendor_verity_block_device", "verity_block_device")
+    copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
   elif mount_point == "oem":
     copy_prop("fs_type", "fs_type")
     copy_prop("oem_size", "partition_size")
     copy_prop("oem_journal_size", "journal_size")
+    copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
 
   return d
 
@@ -424,7 +462,8 @@
 
   glob_dict = LoadGlobalDict(glob_dict_file)
   if "mount_point" in glob_dict:
-    # The caller knows the mount point and provides a dictionay needed by BuildImage().
+    # The caller knows the mount point and provides a dictionay needed by
+    # BuildImage().
     image_properties = glob_dict
   else:
     image_filename = os.path.basename(out_file)