am 0068d25b: Include drawables for all densities - b/11270325

* commit '0068d25b4895162993118fe3b61d2775fa575e70':
  Include drawables for all densities - b/11270325
diff --git a/core/Makefile b/core/Makefile
index 298eef1..fca06fa 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1260,7 +1260,7 @@
 ifdef PRODUCT_EXTRA_RECOVERY_KEYS
 	$(hide) echo "extra_recovery_keys=$(PRODUCT_EXTRA_RECOVERY_KEYS)" >> $(zip_root)/META/misc_info.txt
 endif
-	$(hide) echo "mkbootimg_args=$(BOARD_MKBOOTIMG_ARGS)" >> $(zip_root)/META/misc_info.txt
+	$(hide) echo 'mkbootimg_args=$(BOARD_MKBOOTIMG_ARGS)' >> $(zip_root)/META/misc_info.txt
 	$(hide) echo "use_set_metadata=1" >> $(zip_root)/META/misc_info.txt
 	$(call generate-userimage-prop-dictionary, $(zip_root)/META/misc_info.txt)
 	@# Zip everything up, preserving symlinks
@@ -1295,7 +1295,8 @@
 
 $(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(DISTTOOLS)
 	@echo "Package OTA: $@"
-	$(hide) ./build/tools/releasetools/ota_from_target_files -v \
+	$(hide) MKBOOTIMG=$(BOARD_CUSTOM_MKBOOTIMG) \
+	   ./build/tools/releasetools/ota_from_target_files -v \
 	   -p $(HOST_OUT) \
 	   -k $(KEY_CERT_PAIR) \
 	   $(BUILT_TARGET_FILES_PACKAGE) $@
@@ -1323,7 +1324,8 @@
 
 $(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(DISTTOOLS)
 	@echo "Package: $@"
-	$(hide) ./build/tools/releasetools/img_from_target_files -v \
+	$(hide) MKBOOTIMG=$(BOARD_CUSTOM_MKBOOTIMG) \
+	   ./build/tools/releasetools/img_from_target_files -v \
 	   -s $(extensions) \
 	   -p $(HOST_OUT) \
 	   $(BUILT_TARGET_FILES_PACKAGE) $@
diff --git a/core/binary.mk b/core/binary.mk
index 554b8c7..8685060 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -127,10 +127,12 @@
 ####################################################
 ## Add FDO flags if FDO is turned on and supported
 ####################################################
-ifeq ($(strip $(LOCAL_NO_FDO_SUPPORT)),)
-  LOCAL_CFLAGS += $(TARGET_FDO_CFLAGS)
-  LOCAL_CPPFLAGS += $(TARGET_FDO_CFLAGS)
-  LOCAL_LDFLAGS += $(TARGET_FDO_CFLAGS)
+ifneq ($(strip $(LOCAL_FDO_SUPPORT)),)
+  ifeq ($(strip $(LOCAL_IS_HOST_MODULE)),)
+    LOCAL_CFLAGS += $(TARGET_FDO_CFLAGS)
+    LOCAL_CPPFLAGS += $(TARGET_FDO_CFLAGS)
+    LOCAL_LDFLAGS += $(TARGET_FDO_CFLAGS)
+  endif
 endif
 
 ####################################################
@@ -177,6 +179,20 @@
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_NO_DEFAULT_COMPILER_FLAGS := \
     $(strip $(LOCAL_NO_DEFAULT_COMPILER_FLAGS))
 
+ifeq ($(strip $(WITH_SYNTAX_CHECK)),)
+  LOCAL_NO_SYNTAX_CHECK := true
+endif
+
+ifeq ($(strip $(WITH_STATIC_ANALYZER)),)
+  LOCAL_NO_STATIC_ANALYZER := true
+endif
+
+ifneq ($(strip $(LOCAL_IS_HOST_MODULE)),)
+  my_syntax_arch := host
+else
+  my_syntax_arch := $(TARGET_ARCH)
+endif
+
 ifeq ($(strip $(LOCAL_CC)),)
   ifeq ($(strip $(LOCAL_CLANG)),true)
     LOCAL_CC := $(CLANG)
@@ -184,6 +200,13 @@
     LOCAL_CC := $($(my_prefix)CC)
   endif
 endif
+ifneq ($(LOCAL_NO_STATIC_ANALYZER),true)
+  LOCAL_CC := $(SYNTAX_TOOLS_PREFIX)/ccc-analyzer $(my_syntax_arch) "$(LOCAL_CC)"
+else
+ifneq ($(LOCAL_NO_SYNTAX_CHECK),true)
+  LOCAL_CC := $(SYNTAX_TOOLS_PREFIX)/ccc-syntax $(my_syntax_arch) "$(LOCAL_CC)"
+endif
+endif
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CC := $(LOCAL_CC)
 
 ifeq ($(strip $(LOCAL_CXX)),)
@@ -193,6 +216,13 @@
     LOCAL_CXX := $($(my_prefix)CXX)
   endif
 endif
+ifneq ($(LOCAL_NO_STATIC_ANALYZER),true)
+  LOCAL_CXX := $(SYNTAX_TOOLS_PREFIX)/cxx-analyzer $(my_syntax_arch) "$(LOCAL_CXX)"
+else
+ifneq ($(LOCAL_NO_SYNTAX_CHECK),true)
+  LOCAL_CXX := $(SYNTAX_TOOLS_PREFIX)/cxx-syntax $(my_syntax_arch) "$(LOCAL_CXX)"
+endif
+endif
 $(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_CXX := $(LOCAL_CXX)
 
 # TODO: support a mix of standard extensions so that this isn't necessary
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index a8b7b28..0a3517b 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -37,7 +37,7 @@
 LOCAL_CXX:=
 LOCAL_CPP_EXTENSION:=
 LOCAL_NO_DEFAULT_COMPILER_FLAGS:=
-LOCAL_NO_FDO_SUPPORT :=
+LOCAL_FDO_SUPPORT:=
 LOCAL_ARM_MODE:=
 LOCAL_YACCFLAGS:=
 LOCAL_ASFLAGS:=
@@ -141,6 +141,8 @@
 LOCAL_POST_INSTALL_CMD:=
 LOCAL_DIST_BUNDLED_BINARIES:=
 LOCAL_HAL_STATIC_LIBRARIES:=
+LOCAL_NO_SYNTAX_CHECK:=
+LOCAL_NO_STATIC_ANALYZER:=
 
 # Trim MAKEFILE_LIST so that $(call my-dir) doesn't need to
 # iterate over thousands of entries every time.
diff --git a/core/combo/TARGET_linux-aarch64.mk b/core/combo/TARGET_linux-aarch64.mk
new file mode 100644
index 0000000..56dd157
--- /dev/null
+++ b/core/combo/TARGET_linux-aarch64.mk
@@ -0,0 +1,232 @@
+#
+# Copyright (C) 2013 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.
+#
+
+# Configuration for Linux on ARM.
+# Included by combo/select.mk
+
+# You can set TARGET_ARCH_VARIANT to use an arch version other
+# than ARMv5TE. Each value should correspond to a file named
+# $(BUILD_COMBOS)/arch/<name>.mk which must contain
+# makefile variable definitions similar to the preprocessor
+# defines in build/core/combo/include/arch/<combo>/AndroidConfig.h. Their
+# purpose is to allow module Android.mk files to selectively compile
+# different versions of code based upon the funtionality and
+# instructions available in a given architecture version.
+#
+# The blocks also define specific arch_variant_cflags, which
+# include defines, and compiler settings for the given architecture
+# version.
+#
+ifeq ($(strip $(TARGET_ARCH_VARIANT)),)
+TARGET_ARCH_VARIANT := armv8
+endif
+
+ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
+TARGET_GCC_VERSION := 4.8
+else
+TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
+endif
+
+TARGET_ARCH_SPECIFIC_MAKEFILE := $(BUILD_COMBOS)/arch/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT).mk
+ifeq ($(strip $(wildcard $(TARGET_ARCH_SPECIFIC_MAKEFILE))),)
+$(error Unknown ARM architecture version: $(TARGET_ARCH_VARIANT))
+endif
+
+include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
+
+# You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
+ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
+TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/aarch64/aarch64-linux-android-$(TARGET_GCC_VERSION)
+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_STRIP := $(TARGET_TOOLS_PREFIX)strip$(HOST_EXECUTABLE_SUFFIX)
+ifeq ($(TARGET_BUILD_VARIANT),user)
+    TARGET_STRIP_COMMAND = $(TARGET_STRIP) --strip-all $< -o $@
+else
+    TARGET_STRIP_COMMAND = $(TARGET_STRIP) --strip-all $< -o $@ && \
+        $(TARGET_OBJCOPY) --add-gnu-debuglink=$< $@
+endif
+
+TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
+
+android_config_h := $(call select-android-config-h,linux-aarch64)
+
+TARGET_GLOBAL_CFLAGS += \
+			-fpic -fPIE \
+			$(arch_variant_cflags) \
+			-include $(android_config_h) \
+			-I $(dir $(android_config_h))
+
+TARGET_GLOBAL_CFLAGS += \
+			-fpic -fPIE \
+			-ffunction-sections \
+			-fdata-sections \
+			-funwind-tables \
+			-Wa,--noexecstack \
+			-Werror=format-security \
+			-D_FORTIFY_SOURCE=2 \
+			-fno-short-enums \
+			$(arch_variant_cflags) \
+			-include $(android_config_h) \
+			-I $(dir $(android_config_h))
+
+TARGET_GLOBAL_CFLAGS += -fno-strict-volatile-bitfields
+
+# This is to avoid the dreaded warning compiler message:
+#   note: the mangling of 'va_list' has changed in GCC 4.4
+#
+# The fact that the mangling changed does not affect the NDK ABI
+# very fortunately (since none of the exposed APIs used va_list
+# in their exported C++ functions). Also, GCC 4.5 has already
+# removed the warning from the compiler.
+#
+TARGET_GLOBAL_CFLAGS += -Wno-psabi
+
+TARGET_GLOBAL_LDFLAGS += \
+			-Wl,-z,noexecstack \
+			-Wl,-z,relro \
+			-Wl,-z,now \
+			-Wl,--warn-shared-textrel \
+			-Wl,--fatal-warnings \
+			$(arch_variant_ldflags)
+
+TARGET_GLOBAL_CPPFLAGS += -fvisibility-inlines-hidden
+
+# More flags/options can be added here
+TARGET_RELEASE_CFLAGS := \
+			-DNDEBUG \
+			-O2 -g \
+			-Wstrict-aliasing=2 \
+			-fgcse-after-reload \
+			-frerun-cse-after-loop \
+			-frename-registers
+
+libc_root := bionic/libc
+libm_root := bionic/libm
+libstdc++_root := bionic/libstdc++
+libthread_db_root := bionic/libthread_db
+
+
+# unless CUSTOM_KERNEL_HEADERS is defined, we're going to use
+# symlinks located in out/ to point to the appropriate kernel
+# headers. see 'config/kernel_headers.make' for more details
+#
+ifneq ($(CUSTOM_KERNEL_HEADERS),)
+    KERNEL_HEADERS_COMMON := $(CUSTOM_KERNEL_HEADERS)
+    KERNEL_HEADERS_ARCH   := $(CUSTOM_KERNEL_HEADERS)
+else
+    KERNEL_HEADERS_COMMON := $(libc_root)/kernel/uapi
+    KERNEL_HEADERS_ARCH   := $(libc_root)/kernel/uapi/arch-$(TARGET_ARCH)
+endif
+KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
+
+TARGET_C_INCLUDES := \
+	$(libc_root)/arch-aarch64/include \
+	$(libc_root)/include \
+	$(libstdc++_root)/include \
+	$(KERNEL_HEADERS) \
+	$(libm_root)/include \
+	$(libm_root)/include/aarch64 \
+	$(libthread_db_root)/include
+
+# FIXME
+# CRT* objects to be added later
+TARGET_CRTBEGIN_STATIC_O :=
+TARGET_CRTBEGIN_DYNAMIC_O :=
+TARGET_CRTEND_O :=
+
+TARGET_CRTBEGIN_SO_O :=
+TARGET_CRTEND_SO_O :=
+
+TARGET_STRIP_MODULE:=true
+
+TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libm
+
+TARGET_CUSTOM_LD_COMMAND := true
+
+define transform-o-to-shared-lib-inner
+$(hide) $(PRIVATE_CXX) \
+	-nostdlib -Wl,-soname,$(notdir $@) \
+	-Wl,-shared,-Bsymbolic \
+	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_SO_O)) \
+	$(PRIVATE_ALL_OBJECTS) \
+	-Wl,--whole-archive \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+	-Wl,--no-whole-archive \
+	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
+	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
+	$(PRIVATE_TARGET_FDO_LIB) \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+	-o $@ \
+	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
+	$(PRIVATE_LDFLAGS) \
+	$(PRIVATE_TARGET_LIBGCC) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_SO_O))
+endef
+
+define transform-o-to-executable-inner
+$(hide) $(PRIVATE_CXX) -nostdlib -Bdynamic -fPIE -pie \
+	-Wl,-dynamic-linker,/system/bin/linker64 \
+	-Wl,-z,nocopyreloc \
+	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
+	-Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O)) \
+	$(PRIVATE_ALL_OBJECTS) \
+	-Wl,--whole-archive \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+	-Wl,--no-whole-archive \
+	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
+	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
+	$(PRIVATE_TARGET_FDO_LIB) \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+	-o $@ \
+	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
+	$(PRIVATE_LDFLAGS) \
+	$(PRIVATE_TARGET_LIBGCC) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O))
+endef
+
+define transform-o-to-static-executable-inner
+$(hide) $(PRIVATE_CXX) -Bstatic \
+	-o $@ \
+	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_STATIC_O)) \
+	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
+	$(PRIVATE_LDFLAGS) \
+	$(PRIVATE_ALL_OBJECTS) \
+	-Wl,--whole-archive \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+	-Wl,--no-whole-archive \
+	$(call normalize-target-libraries,$(filter-out %libc_nomalloc.a,$(filter-out %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)))) \
+	-Wl,--start-group \
+	$(call normalize-target-libraries,$(filter %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
+	$(call normalize-target-libraries,$(filter %libc_nomalloc.a,$(PRIVATE_ALL_STATIC_LIBRARIES))) \
+	$(PRIVATE_TARGET_FDO_LIB) \
+	$(PRIVATE_TARGET_LIBGCC) \
+	-Wl,--end-group \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O))
+endef
diff --git a/core/combo/TARGET_linux-arm.mk b/core/combo/TARGET_linux-arm.mk
index 4d0d936..8d012f3 100644
--- a/core/combo/TARGET_linux-arm.mk
+++ b/core/combo/TARGET_linux-arm.mk
@@ -109,11 +109,11 @@
 			-include $(android_config_h) \
 			-I $(dir $(android_config_h))
 
-# This warning causes dalvik not to build with gcc 4.6+ and -Werror.
-# We cannot turn it off blindly since the option is not available
-# in gcc-4.4.x.  We also want to disable sincos optimization globally
-# by turning off the builtin sin function.
-ifneq ($(filter 4.6 4.6.% 4.7 4.7.%, $(TARGET_GCC_VERSION)),)
+# The "-Wunused-but-set-variable" option often breaks projects that enable
+# "-Wall -Werror" due to a commom idiom "ALOGV(mesg)" where ALOGV is turned
+# into no-op in some builds while mesg is defined earlier. So we explicitly
+# disable "-Wunused-but-set-variable" here.
+ifneq ($(filter 4.6 4.6.% 4.7 4.7.% 4.8, $(TARGET_GCC_VERSION)),)
 TARGET_GLOBAL_CFLAGS += -Wno-unused-but-set-variable -fno-builtin-sin \
 			-fno-strict-volatile-bitfields
 endif
@@ -245,11 +245,11 @@
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
 	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
+	$(PRIVATE_TARGET_FDO_LIB) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
 	-o $@ \
 	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
 	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_FDO_LIB) \
 	$(PRIVATE_TARGET_LIBGCC) \
 	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_SO_O))
 endef
@@ -270,11 +270,11 @@
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
 	$(if $(TARGET_BUILD_APPS),$(PRIVATE_TARGET_LIBGCC)) \
+	$(PRIVATE_TARGET_FDO_LIB) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
 	-o $@ \
 	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
 	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_FDO_LIB) \
 	$(PRIVATE_TARGET_LIBGCC) \
 	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O))
 endef
diff --git a/core/combo/TARGET_linux-mips.mk b/core/combo/TARGET_linux-mips.mk
index a20465b..ba6e8cd 100644
--- a/core/combo/TARGET_linux-mips.mk
+++ b/core/combo/TARGET_linux-mips.mk
@@ -236,11 +236,11 @@
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
 	$(PRIVATE_TARGET_LIBGCC) \
+	$(PRIVATE_TARGET_FDO_LIB) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
 	-o $@ \
 	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
 	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_FDO_LIB) \
 	$(PRIVATE_TARGET_LIBGCC) \
 	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_SO_O))
 endef
@@ -261,11 +261,11 @@
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
 	$(PRIVATE_TARGET_LIBGCC) \
+	$(PRIVATE_TARGET_FDO_LIB) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
 	-o $@ \
 	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
 	$(PRIVATE_LDFLAGS) \
-	$(PRIVATE_TARGET_FDO_LIB) \
 	$(PRIVATE_TARGET_LIBGCC) \
 	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O))
 endef
diff --git a/core/combo/TARGET_linux-x86.mk b/core/combo/TARGET_linux-x86.mk
old mode 100644
new mode 100755
index d5772b1..dfd463f
--- a/core/combo/TARGET_linux-x86.mk
+++ b/core/combo/TARGET_linux-x86.mk
@@ -42,8 +42,8 @@
 
 # You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
 ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
-TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/i686-linux-android-$(TARGET_GCC_VERSION)
-TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/i686-linux-android-
+TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/x86_64-linux-android-$(TARGET_GCC_VERSION)
+TARGET_TOOLS_PREFIX := $(TARGET_TOOLCHAIN_ROOT)/bin/x86_64-linux-android-
 endif
 
 TARGET_CC := $(TARGET_TOOLS_PREFIX)gcc$(HOST_EXECUTABLE_SUFFIX)
@@ -63,6 +63,8 @@
 ifneq ($(wildcard $(TARGET_CC)),)
 TARGET_LIBGCC := \
 	$(shell $(TARGET_CC) -m32 -print-file-name=libgcc.a)
+target_libgcov := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
+	-print-file-name=libgcov.a)
 endif
 
 TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
@@ -72,6 +74,34 @@
 libstdc++_root := bionic/libstdc++
 libthread_db_root := bionic/libthread_db
 
+# Define FDO (Feedback Directed Optimization) options.
+
+TARGET_FDO_CFLAGS:=
+TARGET_FDO_LIB:=
+
+ifneq ($(strip $(BUILD_FDO_INSTRUMENT)),)
+  # Set BUILD_FDO_INSTRUMENT=true to turn on FDO instrumentation.
+  # The profile will be generated on /data/local/tmp/profile on the device.
+  TARGET_FDO_CFLAGS := -fprofile-generate=/data/local/tmp/profile -DANDROID_FDO
+  TARGET_FDO_LIB := $(target_libgcov)
+else
+  # If BUILD_FDO_INSTRUMENT is turned off, then consider doing the FDO optimizations.
+  # Set TARGET_FDO_PROFILE_PATH to set a custom profile directory for your build.
+  ifeq ($(strip $(TARGET_FDO_PROFILE_PATH)),)
+    TARGET_FDO_PROFILE_PATH := fdo/profiles/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT)
+  else
+    ifeq ($(strip $(wildcard $(TARGET_FDO_PROFILE_PATH))),)
+      $(warning Custom TARGET_FDO_PROFILE_PATH supplied, but directory does not exist. Turn off FDO.)
+    endif
+  endif
+
+  # If the FDO profile directory can't be found, then FDO is off.
+  ifneq ($(strip $(wildcard $(TARGET_FDO_PROFILE_PATH))),)
+    TARGET_FDO_CFLAGS := -fprofile-use=$(TARGET_FDO_PROFILE_PATH) -DANDROID_FDO
+    TARGET_FDO_LIB := $(target_libgcov)
+  endif
+endif
+
 # unless CUSTOM_KERNEL_HEADERS is defined, we're going to use
 # symlinks located in out/ to point to the appropriate kernel
 # headers. see 'config/kernel_headers.make' for more details
@@ -104,6 +134,7 @@
 			-funswitch-loops \
 			-funwind-tables \
 			-fstack-protector \
+			-m32 \
 			-include $(android_config_h) \
 			-I $(dir $(android_config_h))
 
@@ -111,23 +142,29 @@
 TARGET_GLOBAL_CPPFLAGS += \
 			-fno-use-cxa-atexit
 
-# XXX: Our toolchain is normally configured to always set these flags by default
-# however, there have been reports that this is sometimes not the case. So make
-# them explicit here unless we have the time to carefully check it
-#
-TARGET_GLOBAL_CFLAGS += -mstackrealign -msse3 -mfpmath=sse -m32
-
-# XXX: These flags should not be defined here anymore. Instead, the Android.mk
-# of the modules that depend on these features should instead check the
-# corresponding macros (e.g. ARCH_X86_HAVE_SSE2 and ARCH_X86_HAVE_SSSE3)
-# Keep them here until this is all cleared up.
-#
-ifeq ($(ARCH_X86_HAVE_SSE2),true)
-TARGET_GLOBAL_CFLAGS += -DUSE_SSE2
-endif
+TARGET_GLOBAL_CFLAGS += $(arch_variant_cflags)
+TARGET_GLOBAL_CFLAGS += -mmmx
+TARGET_GLOBAL_CFLAGS += -msse
+TARGET_GLOBAL_CFLAGS += -DUSE_SSE2 -msse2
+TARGET_GLOBAL_CFLAGS += -msse3
 
 ifeq ($(ARCH_X86_HAVE_SSSE3),true)   # yes, really SSSE3, not SSE3!
-TARGET_GLOBAL_CFLAGS += -DUSE_SSSE3
+    TARGET_GLOBAL_CFLAGS += -DUSE_SSSE3 -mssse3
+endif
+ifeq ($(ARCH_X86_HAVE_SSE4),true)
+    TARGET_GLOBAL_CFLAGS += -msse4
+endif
+ifeq ($(ARCH_X86_HAVE_SSE4_1),true)
+    TARGET_GLOBAL_CFLAGS += -msse4.1
+endif
+ifeq ($(ARCH_X86_HAVE_SSE4_2),true)
+    TARGET_GLOBAL_CFLAGS += -msse4.2
+endif
+ifeq ($(ARCH_X86_HAVE_AVX),true)
+    TARGET_GLOBAL_CFLAGS += -mavx
+endif
+ifeq ($(ARCH_X86_HAVE_AES_NI),true)
+    TARGET_GLOBAL_CFLAGS += -maes
 endif
 
 # XXX: This flag is probably redundant. I believe our toolchain always sets
@@ -143,10 +180,6 @@
 #
 TARGET_GLOBAL_CFLAGS += -D__ANDROID__
 
-# XXX: This flag is probably redundant since our toolchain binaries already
-# generate 32-bit machine code. It probably dates back to the old days
-# where we were using the host toolchain on Linux to build the platform
-# images. Consider it for removal.
 TARGET_GLOBAL_LDFLAGS += -m32
 
 TARGET_GLOBAL_LDFLAGS += -Wl,-z,noexecstack
@@ -191,6 +224,7 @@
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
 	$(PRIVATE_TARGET_LIBGCC) \
+	$(PRIVATE_TARGET_FDO_LIB) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
 	-o $@ \
 	$(PRIVATE_LDFLAGS) \
@@ -202,7 +236,6 @@
 $(hide) $(PRIVATE_CXX) \
 	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
 	-nostdlib -Bdynamic \
-	-Wl,-dynamic-linker,/system/bin/linker \
 	-Wl,-z,nocopyreloc \
 	-fPIE -pie \
 	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
@@ -216,6 +249,7 @@
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
 	$(PRIVATE_TARGET_LIBGCC) \
+	$(PRIVATE_TARGET_FDO_LIB) \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
 	-o $@ \
 	$(PRIVATE_LDFLAGS) \
@@ -237,25 +271,8 @@
 	-Wl,--no-whole-archive \
 	-Wl,--start-group \
 	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+	$(PRIVATE_TARGET_FDO_LIB) \
 	$(PRIVATE_TARGET_LIBGCC) \
 	-Wl,--end-group \
 	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O))
 endef
-
-# Special check for x86 NDK ABI compatibility.
-# The TARGET_CPU_ABI variable should be defined in BoardConfig.mk to 'x86'
-# *only* if the platform image is compatible with the NDK x86 ABI.
-#
-# We perform a small check here to ensure that nothing bad can happen.
-#
-ifeq ($(TARGET_CPU_ABI),x86)
-  ifneq (true-true-true-true,$(ARCH_X86_HAVE_MMX)-$(ARCH_X86_HAVE_SSE)-$(ARCH_X86_HAVE_SSE2)-$(ARCH_X86_HAVE_SSE3))
-    $(info ERROR: Your x86 platform image is not compatible with the NDK x86 ABI)
-    $(info As such, you should *not* define TARGET_CPU_ABI to 'x86' in your BoardConfig.mk)
-    $(info to ensure that your device will not be mistakenly listed as compatible by
-    $(info the Android Market. Also, it is likely that the image will fail the CTS tests)
-    $(info Please undefine TARGET_CPU_ABI in your BoardConfig.mk, or select the value 'none')
-    $(info The corresponding image will still be able to run Dalvik-based Android applications)
-    $(error Aborting build! Please fix your BoardConfig.mk)
-  endif
-endif
diff --git a/core/combo/TARGET_linux-x86_64.mk b/core/combo/TARGET_linux-x86_64.mk
new file mode 100755
index 0000000..86d29f5
--- /dev/null
+++ b/core/combo/TARGET_linux-x86_64.mk
@@ -0,0 +1,276 @@
+#
+# Copyright (C) 2006 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.
+#
+
+# Configuration for Linux on x86_64 as a target.
+# Included by combo/select.mk
+
+# Provide a default variant.
+ifeq ($(strip $(TARGET_ARCH_VARIANT)),)
+TARGET_ARCH_VARIANT := x86_64
+endif
+
+ifeq ($(strip $(TARGET_GCC_VERSION_EXP)),)
+TARGET_GCC_VERSION := 4.7
+else
+TARGET_GCC_VERSION := $(TARGET_GCC_VERSION_EXP)
+endif
+
+# Include the arch-variant-specific configuration file.
+# Its role is to define various ARCH_X86_HAVE_XXX feature macros,
+# plus initial values for TARGET_GLOBAL_CFLAGS
+#
+TARGET_ARCH_SPECIFIC_MAKEFILE := $(BUILD_COMBOS)/arch/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT).mk
+ifeq ($(strip $(wildcard $(TARGET_ARCH_SPECIFIC_MAKEFILE))),)
+$(error Unknown $(TARGET_ARCH) architecture version: $(TARGET_ARCH_VARIANT))
+endif
+
+include $(TARGET_ARCH_SPECIFIC_MAKEFILE)
+
+
+# You can set TARGET_TOOLS_PREFIX to get gcc from somewhere else
+ifeq ($(strip $(TARGET_TOOLS_PREFIX)),)
+TARGET_TOOLCHAIN_ROOT := prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/x86_64-linux-android-$(TARGET_GCC_VERSION)
+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_STRIP := $(TARGET_TOOLS_PREFIX)strip$(HOST_EXECUTABLE_SUFFIX)
+
+ifeq ($(TARGET_BUILD_VARIANT),user)
+TARGET_STRIP_COMMAND = $(TARGET_STRIP) --strip-debug $< -o $@
+else
+TARGET_STRIP_COMMAND = $(TARGET_STRIP) --strip-debug $< -o $@ && \
+	$(TARGET_OBJCOPY) --add-gnu-debuglink=$< $@
+endif
+
+ifneq ($(wildcard $(TARGET_CC)),)
+TARGET_LIBGCC := \
+	$(shell $(TARGET_CC) -m64 -print-file-name=libgcc.a)
+target_libgcov := $(shell $(TARGET_CC) $(TARGET_GLOBAL_CFLAGS) \
+	-print-file-name=libgcov.a)
+endif
+
+TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
+
+libc_root := bionic/libc
+libm_root := bionic/libm
+libstdc++_root := bionic/libstdc++
+libthread_db_root := bionic/libthread_db
+
+# Define FDO (Feedback Directed Optimization) options.
+
+TARGET_FDO_CFLAGS:=
+TARGET_FDO_LIB:=
+
+ifneq ($(strip $(BUILD_FDO_INSTRUMENT)),)
+  # Set BUILD_FDO_INSTRUMENT=true to turn on FDO instrumentation.
+  # The profile will be generated on /data/local/tmp/profile on the device.
+  TARGET_FDO_CFLAGS := -fprofile-generate=/data/local/tmp/profile -DANDROID_FDO
+  TARGET_FDO_LIB := $(target_libgcov)
+else
+  # If BUILD_FDO_INSTRUMENT is turned off, then consider doing the FDO optimizations.
+  # Set TARGET_FDO_PROFILE_PATH to set a custom profile directory for your build.
+  ifeq ($(strip $(TARGET_FDO_PROFILE_PATH)),)
+    TARGET_FDO_PROFILE_PATH := fdo/profiles/$(TARGET_ARCH)/$(TARGET_ARCH_VARIANT)
+  else
+    ifeq ($(strip $(wildcard $(TARGET_FDO_PROFILE_PATH))),)
+      $(warning Custom TARGET_FDO_PROFILE_PATH supplied, but directory does not exist. Turn off FDO.)
+    endif
+  endif
+
+  # If the FDO profile directory can't be found, then FDO is off.
+  ifneq ($(strip $(wildcard $(TARGET_FDO_PROFILE_PATH))),)
+    TARGET_FDO_CFLAGS := -fprofile-use=$(TARGET_FDO_PROFILE_PATH) -DANDROID_FDO
+    TARGET_FDO_LIB := $(target_libgcov)
+  endif
+endif
+
+# unless CUSTOM_KERNEL_HEADERS is defined, we're going to use
+# symlinks located in out/ to point to the appropriate kernel
+# headers. see 'config/kernel_headers.make' for more details
+#
+ifneq ($(CUSTOM_KERNEL_HEADERS),)
+    KERNEL_HEADERS_COMMON := $(CUSTOM_KERNEL_HEADERS)
+    KERNEL_HEADERS_ARCH   := $(CUSTOM_KERNEL_HEADERS)
+else
+    KERNEL_HEADERS_COMMON := $(libc_root)/kernel/common
+    KERNEL_HEADERS_ARCH   := $(libc_root)/kernel/arch-$(TARGET_ARCH)
+endif
+KERNEL_HEADERS := $(KERNEL_HEADERS_COMMON) $(KERNEL_HEADERS_ARCH)
+
+TARGET_GLOBAL_CFLAGS += \
+			-O2 \
+			-Ulinux \
+			-Wa,--noexecstack \
+			-Werror=format-security \
+			-D_FORTIFY_SOURCE=2 \
+			-Wstrict-aliasing=2 \
+			-fPIC -fPIE \
+			-ffunction-sections \
+			-finline-functions \
+			-finline-limit=300 \
+			-fno-inline-functions-called-once \
+			-fno-short-enums \
+			-fstrict-aliasing \
+			-funswitch-loops \
+			-funwind-tables \
+			-fstack-protector \
+			-m64
+
+android_config_h := $(call select-android-config-h,target_linux-x86)
+TARGET_ANDROID_CONFIG_CFLAGS := -include $(android_config_h) -I $(dir $(android_config_h))
+TARGET_GLOBAL_CFLAGS += $(TARGET_ANDROID_CONFIG_CFLAGS)
+
+# XXX: Not sure this is still needed. Must check with our toolchains.
+TARGET_GLOBAL_CPPFLAGS += \
+			-fno-use-cxa-atexit
+
+TARGET_GLOBAL_CFLAGS += $(arch_variant_cflags) \
+			-mstackrealign \
+			-mfpmath=sse
+
+ifeq ($(ARCH_X86_HAVE_SSSE3),true)   # yes, really SSSE3, not SSE3!
+    TARGET_GLOBAL_CFLAGS += -DUSE_SSSE3 -mssse3
+endif
+ifeq ($(ARCH_X86_HAVE_SSE4),true)
+    TARGET_GLOBAL_CFLAGS += -msse4
+endif
+ifeq ($(ARCH_X86_HAVE_SSE4_1),true)
+    TARGET_GLOBAL_CFLAGS += -msse4.1
+endif
+ifeq ($(ARCH_X86_HAVE_SSE4_2),true)
+    TARGET_GLOBAL_CFLAGS += -msse4.2
+endif
+ifeq ($(ARCH_X86_HAVE_AVX),true)
+    TARGET_GLOBAL_CFLAGS += -mavx
+endif
+ifeq ($(ARCH_X86_HAVE_AES_NI),true)
+    TARGET_GLOBAL_CFLAGS += -maes
+endif
+
+# XXX: This flag is probably redundant. I believe our toolchain always sets
+# it by default. Consider for removal.
+#
+TARGET_GLOBAL_CFLAGS += -mbionic
+
+# XXX: This flag is probably redundant. The macro should be defined by our
+# toolchain binaries automatically (as a compiler built-in).
+# Check with: $BINPREFIX-gcc -dM -E < /dev/null
+#
+# Consider for removal.
+#
+TARGET_GLOBAL_CFLAGS += -D__ANDROID__
+
+TARGET_GLOBAL_LDFLAGS += -m64
+
+TARGET_GLOBAL_LDFLAGS += -Wl,-z,noexecstack
+TARGET_GLOBAL_LDFLAGS += -Wl,-z,relro -Wl,-z,now
+TARGET_GLOBAL_LDFLAGS += -Wl,--warn-shared-textrel
+TARGET_GLOBAL_LDFLAGS += -Wl,--gc-sections
+
+TARGET_C_INCLUDES := \
+	$(libc_root)/arch-x86_64/include \
+	$(libc_root)/include \
+	$(libstdc++_root)/include \
+	$(KERNEL_HEADERS) \
+	$(libm_root)/include \
+	$(libm_root)/include/amd64 \
+	$(libthread_db_root)/include
+
+TARGET_CRTBEGIN_STATIC_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_static.o
+TARGET_CRTBEGIN_DYNAMIC_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtbegin_dynamic.o
+TARGET_CRTEND_O := $(TARGET_OUT_INTERMEDIATE_LIBRARIES)/crtend_android.o
+
+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 libstdc++ libm
+
+TARGET_CUSTOM_LD_COMMAND := true
+define transform-o-to-shared-lib-inner
+$(hide) $(PRIVATE_CXX) \
+	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
+	 -nostdlib -Wl,-soname,$(notdir $@) \
+	 -shared -Bsymbolic \
+	$(TARGET_GLOBAL_CFLAGS) \
+	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_SO_O)) \
+	$(PRIVATE_ALL_OBJECTS) \
+	-Wl,--whole-archive \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+	-Wl,--no-whole-archive \
+	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
+	$(PRIVATE_TARGET_LIBGCC) \
+	$(PRIVATE_TARGET_FDO_LIB) \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+	-o $@ \
+	$(PRIVATE_LDFLAGS) \
+	$(PRIVATE_TARGET_LIBGCC) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_SO_O))
+endef
+
+define transform-o-to-executable-inner
+$(hide) $(PRIVATE_CXX) \
+	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
+	-nostdlib -Bdynamic \
+	-Wl,-z,nocopyreloc \
+	-fPIE -pie \
+	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
+	-Wl,-rpath-link=$(TARGET_OUT_INTERMEDIATE_LIBRARIES) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_DYNAMIC_O)) \
+	$(PRIVATE_ALL_OBJECTS) \
+	-Wl,--whole-archive \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+	-Wl,--no-whole-archive \
+	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--start-group) \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+	$(if $(PRIVATE_GROUP_STATIC_LIBRARIES),-Wl$(comma)--end-group) \
+	$(PRIVATE_TARGET_LIBGCC) \
+	$(PRIVATE_TARGET_FDO_LIB) \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_SHARED_LIBRARIES)) \
+	-o $@ \
+	$(PRIVATE_LDFLAGS) \
+	$(PRIVATE_TARGET_LIBGCC) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O))
+endef
+
+define transform-o-to-static-executable-inner
+$(hide) $(PRIVATE_CXX) \
+	$(PRIVATE_TARGET_GLOBAL_LDFLAGS) \
+	-nostdlib -Bstatic \
+	-o $@ \
+	$(PRIVATE_TARGET_GLOBAL_LD_DIRS) \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTBEGIN_STATIC_O)) \
+	$(PRIVATE_LDFLAGS) \
+	$(PRIVATE_ALL_OBJECTS) \
+	-Wl,--whole-archive \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES)) \
+	-Wl,--no-whole-archive \
+	-Wl,--start-group \
+	$(call normalize-target-libraries,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+	$(PRIVATE_TARGET_FDO_LIB) \
+	$(PRIVATE_TARGET_LIBGCC) \
+	-Wl,--end-group \
+	$(if $(filter true,$(PRIVATE_NO_CRT)),,$(PRIVATE_TARGET_CRTEND_O))
+endef
diff --git a/core/combo/arch/aarch64/armv8-a.mk b/core/combo/arch/aarch64/armv8-a.mk
new file mode 100644
index 0000000..edc0497
--- /dev/null
+++ b/core/combo/arch/aarch64/armv8-a.mk
@@ -0,0 +1 @@
+arch_variant_cflags :=
diff --git a/core/combo/arch/arm/armv7-a-neon.mk b/core/combo/arch/arm/armv7-a-neon.mk
index 057ce93..1105330 100644
--- a/core/combo/arch/arm/armv7-a-neon.mk
+++ b/core/combo/arch/arm/armv7-a-neon.mk
@@ -6,7 +6,7 @@
 ARCH_ARM_HAVE_VFP_D32           := true
 ARCH_ARM_HAVE_NEON              := true
 
-ifeq ($(strip $(TARGET_CPU_VARIANT)), cortex-a15)
+ifeq ($(TARGET_CPU_VARIANT),$(filter $(TARGET_CPU_VARIANT),cortex-a15 krait))
 	arch_variant_cflags := -mcpu=cortex-a15
 else
 ifeq ($(strip $(TARGET_CPU_VARIANT)),cortex-a8)
diff --git a/core/combo/arch/mips/mips32r2-fp-xburst.mk b/core/combo/arch/mips/mips32r2-fp-xburst.mk
index fee9cb3..8b0fef1 100644
--- a/core/combo/arch/mips/mips32r2-fp-xburst.mk
+++ b/core/combo/arch/mips/mips32r2-fp-xburst.mk
@@ -10,7 +10,8 @@
     -mtune=mips32r2 \
     -mips32r2 \
     -mhard-float \
-    -mno-fused-madd
+    -mno-fused-madd \
+    -Wa,-mmxu
 
 arch_variant_ldflags := \
     -EL
diff --git a/core/combo/arch/x86/haswell.mk b/core/combo/arch/x86/haswell.mk
new file mode 100644
index 0000000..a00e0a6
--- /dev/null
+++ b/core/combo/arch/x86/haswell.mk
@@ -0,0 +1,16 @@
+# Configuration for Linux on x86.
+# Generating binaries for Haswell processors.
+#
+ARCH_X86_HAVE_SSSE3  := true
+ARCH_X86_HAVE_SSE4   := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AES_NI := true
+ARCH_X86_HAVE_AVX    := true
+
+# CFLAGS for this arch
+arch_variant_cflags := \
+	-march=core-avx2 \
+	-mstackrealign \
+	-mfpmath=sse \
+
diff --git a/core/combo/arch/x86/ivybridge.mk b/core/combo/arch/x86/ivybridge.mk
new file mode 100644
index 0000000..02dc1e0
--- /dev/null
+++ b/core/combo/arch/x86/ivybridge.mk
@@ -0,0 +1,16 @@
+# Configuration for Linux on x86.
+# Generating binaries for Ivy Bridge processors.
+#
+ARCH_X86_HAVE_SSSE3  := true
+ARCH_X86_HAVE_SSE4   := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AES_NI := true
+ARCH_X86_HAVE_AVX    := true
+
+# CFLAGS for this arch
+arch_variant_cflags := \
+	-march=core-avx-i \
+	-mstackrealign \
+	-mfpmath=sse \
+
diff --git a/core/combo/arch/x86/sandybridge.mk b/core/combo/arch/x86/sandybridge.mk
new file mode 100644
index 0000000..dfa540c
--- /dev/null
+++ b/core/combo/arch/x86/sandybridge.mk
@@ -0,0 +1,14 @@
+# Configuration for Linux on x86.
+# Generating binaries for SandyBridge processors.
+#
+ARCH_X86_HAVE_SSSE3  := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX    := true
+
+# CFLAGS for this arch
+arch_variant_cflags := \
+	-march=corei7-avx \
+	-mstackrealign \
+	-mfpmath=sse \
+
diff --git a/core/combo/arch/x86/x86-atom.mk b/core/combo/arch/x86/x86-atom.mk
index 85998e7..508a0af 100644
--- a/core/combo/arch/x86/x86-atom.mk
+++ b/core/combo/arch/x86/x86-atom.mk
@@ -4,15 +4,13 @@
 #
 # See build/core/combo/arch/x86/x86.mk for differences.
 #
-ARCH_X86_HAVE_MMX   := true
-ARCH_X86_HAVE_SSE   := true
-ARCH_X86_HAVE_SSE2  := true
-ARCH_X86_HAVE_SSE3  := true
-
 ARCH_X86_HAVE_SSSE3 := true
 ARCH_X86_HAVE_MOVBE := true
 ARCH_X86_HAVE_POPCNT := false   # popcnt is not supported by current Atom CPUs
 
-# This flag is used to enabled Atom-specific optimizations with our toolchain
-#
-TARGET_GLOBAL_CFLAGS += -march=atom
+# CFLAGS for this arch
+arch_variant_cflags := \
+	-march=atom \
+	-mstackrealign \
+	-mfpmath=sse \
+
diff --git a/core/combo/arch/x86/x86.mk b/core/combo/arch/x86/x86.mk
index 476da45..73706c4 100644
--- a/core/combo/arch/x86/x86.mk
+++ b/core/combo/arch/x86/x86.mk
@@ -1,27 +1,13 @@
 # This file contains feature macro definitions specific to the
-# base 'x86' platform ABI. This one must *strictly* match the NDK x86 ABI
-# which mandates specific CPU extensions to be available.
+# base 'x86' platform ABI.
 #
 # It is also used to build full_x86-eng / sdk_x86-eng platform images that
 # are run in the emulator under KVM emulation (i.e. running directly on
 # the host development machine's CPU).
-#
-
-# If your target device doesn't support the four following features, then
-# it cannot be compatible with the NDK x86 ABI. You should define a new
-# target arch variant (e.g. "x86-mydevice") and a corresponding file
-# under build/core/combo/arch/x86/
-#
-ARCH_X86_HAVE_MMX   := true
-ARCH_X86_HAVE_SSE   := true
-ARCH_X86_HAVE_SSE2  := true
-ARCH_X86_HAVE_SSE3  := true
 
 # These features are optional and shall not be included in the base platform
-# Otherwise, they sdk_x86-eng system images might fail to run on some
+# Otherwise, sdk_x86-eng system images might fail to run on some
 # developer machines.
-#
-
 ARCH_X86_HAVE_SSSE3 := false
 ARCH_X86_HAVE_MOVBE := false
 ARCH_X86_HAVE_POPCNT := false
@@ -32,4 +18,6 @@
 # not always work as intended, so keep it unless we have the time to check
 # everything properly.
 
-TARGET_GLOBAL_CFLAGS += -march=i686
+arch_variant_cflags := \
+    -march=i686 \
+
diff --git a/core/combo/arch/x86_64/haswell.mk b/core/combo/arch/x86_64/haswell.mk
new file mode 100644
index 0000000..9cf95b3
--- /dev/null
+++ b/core/combo/arch/x86_64/haswell.mk
@@ -0,0 +1,13 @@
+# Configuration for Linux on x86_64.
+# Generating binaries for Haswell processors.
+#
+ARCH_X86_HAVE_SSSE3  := true
+ARCH_X86_HAVE_SSE4   := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AES_NI := true
+ARCH_X86_HAVE_AVX    := true
+
+# CFLAGS for this arch
+arch_variant_cflags := \
+	-march=core-avx2
diff --git a/core/combo/arch/x86_64/ivybridge.mk b/core/combo/arch/x86_64/ivybridge.mk
new file mode 100644
index 0000000..7b95190
--- /dev/null
+++ b/core/combo/arch/x86_64/ivybridge.mk
@@ -0,0 +1,13 @@
+# Configuration for Linux on x86_64.
+# Generating binaries for Ivy Bridge processors.
+#
+ARCH_X86_HAVE_SSSE3  := true
+ARCH_X86_HAVE_SSE4   := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AES_NI := true
+ARCH_X86_HAVE_AVX    := true
+
+# CFLAGS for this arch
+arch_variant_cflags := \
+	-march=core-avx-i
diff --git a/core/combo/arch/x86_64/sandybridge.mk b/core/combo/arch/x86_64/sandybridge.mk
new file mode 100644
index 0000000..a443b6b
--- /dev/null
+++ b/core/combo/arch/x86_64/sandybridge.mk
@@ -0,0 +1,11 @@
+# Configuration for Linux on x86_64.
+# Generating binaries for SandyBridge processors.
+#
+ARCH_X86_HAVE_SSSE3  := true
+ARCH_X86_HAVE_SSE4_1 := true
+ARCH_X86_HAVE_SSE4_2 := true
+ARCH_X86_HAVE_AVX    := true
+
+# CFLAGS for this arch
+arch_variant_cflags := \
+	-march=corei7-avx
diff --git a/core/combo/arch/x86_64/x86_64-atom.mk b/core/combo/arch/x86_64/x86_64-atom.mk
new file mode 100755
index 0000000..64b07a0
--- /dev/null
+++ b/core/combo/arch/x86_64/x86_64-atom.mk
@@ -0,0 +1,13 @@
+# This file contains feature macro definitions specific to the
+# 'x86_64-atom' arch variant. This is an extension of the 'x86_64' base variant
+# that adds Atom-specific features.
+#
+# See build/core/combo/arch/x86_64/x86_64.mk for differences.
+#
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_MOVBE := true
+ARCH_X86_HAVE_POPCNT := false   # popcnt is not supported by current Atom CPUs
+
+# CFLAGS for this arch
+arch_variant_cflags := \
+	-march=atom
diff --git a/core/combo/arch/x86_64/x86_64.mk b/core/combo/arch/x86_64/x86_64.mk
new file mode 100755
index 0000000..9d2b620
--- /dev/null
+++ b/core/combo/arch/x86_64/x86_64.mk
@@ -0,0 +1,15 @@
+# This file contains feature macro definitions specific to the
+# base 'x86_64' platform ABI.
+#
+# It is also used to build full_x86_64-eng / sdk_x86_64-eng  platform images
+# that are run in the emulator under KVM emulation (i.e. running directly on
+# the host development machine's CPU).
+
+ARCH_X86_HAVE_SSSE3 := true
+ARCH_X86_HAVE_MOVBE := false # Only supported on Atom.
+ARCH_X86_HAVE_POPCNT := true
+
+
+# CFLAGS for this arch
+arch_variant_cflags := \
+    -march=x86-64
diff --git a/core/combo/include/arch/linux-aarch64/AndroidConfig.h b/core/combo/include/arch/linux-aarch64/AndroidConfig.h
new file mode 100644
index 0000000..77c8912
--- /dev/null
+++ b/core/combo/include/arch/linux-aarch64/AndroidConfig.h
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+/*
+ * Android config -- "android-aarch64".  Used for ARM aarch64 device builds.
+ */
+#ifndef _ANDROID_CONFIG_H
+#define _ANDROID_CONFIG_H
+
+/*
+ * ===========================================================================
+ *                              !!! IMPORTANT !!!
+ * ===========================================================================
+ *
+ * This file is included by ALL C/C++ source files.  Don't put anything in
+ * here unless you are absolutely certain it can't go anywhere else.
+ *
+ * Any C++ stuff must be wrapped with "#ifdef __cplusplus".  Do not use "//"
+ * comments.
+ */
+
+/*
+ * Threading model.  Choose one:
+ *
+ * HAVE_PTHREADS - use the pthreads library.
+ * HAVE_WIN32_THREADS - use Win32 thread primitives.
+ *  -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX
+ */
+#define HAVE_PTHREADS
+
+/*
+ * Do we have pthread_setname_np()?
+ *
+ * (HAVE_PTHREAD_SETNAME_NP is used by WebKit to enable a function with
+ * the same name but different parameters, so we can't use that here.)
+ */
+#define HAVE_ANDROID_PTHREAD_SETNAME_NP
+
+/*
+ * Do we have the futex syscall?
+ */
+#define HAVE_FUTEX
+
+/*
+ * Define if we already have the futex wrapper functions defined. Yes if
+ * compiling against bionic.
+ */
+#define HAVE_FUTEX_WRAPPERS 1
+
+/*
+ * Process creation model.  Choose one:
+ *
+ * HAVE_FORKEXEC - use fork() and exec()
+ * HAVE_WIN32_PROC - use CreateProcess()
+ */
+#define HAVE_FORKEXEC
+
+/*
+ * Process out-of-memory adjustment.  Set if running on Linux,
+ * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory
+ * badness adjustment.
+ */
+#define HAVE_OOM_ADJ
+
+/*
+ * IPC model.  Choose one:
+ *
+ * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget).
+ * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap).
+ * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping).
+ * HAVE_ANDROID_IPC - use Android versions (?, mmap).
+ */
+#define HAVE_ANDROID_IPC
+
+/*
+ * Memory-mapping model. Choose one:
+ *
+ * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h
+ * HAVE_WIN32_FILEMAP - use Win32 filemaps
+ */
+#define  HAVE_POSIX_FILEMAP
+
+/*
+ * Define this if you have <termio.h>
+ */
+#define  HAVE_TERMIO_H 1
+
+/*
+ * Define this if you have <sys/sendfile.h>
+ */
+#define  HAVE_SYS_SENDFILE_H 1
+
+/*
+ * Define this if you build against MSVCRT.DLL
+ */
+/* #define HAVE_MS_C_RUNTIME */
+
+/*
+ * Define this if you have sys/uio.h
+ */
+#define  HAVE_SYS_UIO_H 1
+
+/*
+ * Define this if your platforms implements symbolic links
+ * in its filesystems
+ */
+#define HAVE_SYMLINKS
+
+/*
+ * Define this if we have localtime_r().
+ */
+/* #define HAVE_LOCALTIME_R 1 */
+
+/*
+ * Define this if we have gethostbyname_r().
+ */
+/* #define HAVE_GETHOSTBYNAME_R */
+
+/*
+ * Define this if we have ioctl().
+ */
+#define HAVE_IOCTL
+
+/*
+ * Define this if we want to use WinSock.
+ */
+/* #define HAVE_WINSOCK */
+
+/*
+ * Define this if have clock_gettime() and friends
+ */
+#define HAVE_POSIX_CLOCKS
+
+/*
+ * Define this if we have pthread_cond_timedwait_monotonic() and
+ * clock_gettime(CLOCK_MONOTONIC).
+ */
+#define HAVE_TIMEDWAIT_MONOTONIC
+
+/*
+ * Define this if we have linux style epoll()
+ */
+#define HAVE_EPOLL
+
+/*
+ * Endianness of the target machine.  Choose one:
+ *
+ * HAVE_ENDIAN_H -- have endian.h header we can include.
+ * HAVE_LITTLE_ENDIAN -- we are little endian.
+ * HAVE_BIG_ENDIAN -- we are big endian.
+ */
+#define HAVE_ENDIAN_H
+#define HAVE_LITTLE_ENDIAN
+
+#define _FILE_OFFSET_BITS 64
+#define _LARGEFILE_SOURCE 1
+
+/*
+ * Define if platform has off64_t (and lseek64 and other xxx64 functions)
+ */
+#define HAVE_OFF64_T
+
+/*
+ * Defined if we have the backtrace() call for retrieving a stack trace.
+ * Needed for CallStack to operate; if not defined, CallStack is
+ * non-functional.
+ */
+#define HAVE_BACKTRACE 0
+
+/*
+ * Defined if we have the cxxabi.h header for demangling C++ symbols.  If
+ * not defined, stack crawls will be displayed with raw mangled symbols
+ */
+#define HAVE_CXXABI 0
+
+/*
+ * Defined if we have the gettid() system call.
+ */
+#define HAVE_GETTID
+
+/*
+ * Defined if we have the sched_setscheduler() call
+ */
+#define HAVE_SCHED_SETSCHEDULER
+
+/*
+ * Add any extra platform-specific defines here.
+ */
+#ifndef __linux__
+#define __linux__
+#endif
+
+/*
+ * Define if we have <malloc.h> header
+ */
+#define HAVE_MALLOC_H
+
+/*
+ * Define if we're running on *our* linux on device or emulator.
+ */
+#define HAVE_ANDROID_OS 1
+
+/*
+ * Define if we have Linux-style non-filesystem Unix Domain Sockets
+ */
+#define HAVE_LINUX_LOCAL_SOCKET_NAMESPACE 1
+
+/*
+ * Define if we have Linux's inotify in <sys/inotify.h>.
+ */
+#define HAVE_INOTIFY 1
+
+/*
+ * Define if we have madvise() in <sys/mman.h>
+ */
+#define HAVE_MADVISE 1
+
+/*
+ * Define if tm struct has tm_gmtoff field
+ */
+#define HAVE_TM_GMTOFF 1
+
+/*
+ * Define if dirent struct has d_type field
+ */
+#define HAVE_DIRENT_D_TYPE 1
+
+/*
+ * Define if libc includes Android system properties implementation.
+ */
+#define HAVE_LIBC_SYSTEM_PROPERTIES 1
+
+/*
+ * Define if system provides a system property server (should be
+ * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES).
+ */
+/* #define HAVE_SYSTEM_PROPERTY_SERVER */
+
+/*
+ * What CPU architecture does this platform use?
+ */
+#define ARCH_AARCH64
+
+/*
+ * Define if the size of enums is as short as possible,
+ */
+/* #define HAVE_SHORT_ENUMS */
+
+/*
+ * sprintf() format string for shared library naming.
+ */
+#define OS_SHARED_LIB_FORMAT_STR    "lib%s.so"
+
+/*
+ * Do we have __memcmp16()?
+ */
+#define HAVE__MEMCMP16  1
+
+/*
+ * type for the third argument to mincore().
+ */
+#define MINCORE_POINTER_TYPE unsigned char *
+
+/*
+ * Do we have the sigaction flag SA_NOCLDWAIT?
+ */
+#define HAVE_SA_NOCLDWAIT
+
+/*
+ * The default path separator for the platform
+ */
+#define OS_PATH_SEPARATOR '/'
+
+/*
+ * Is the filesystem case sensitive?
+ */
+#define OS_CASE_SENSITIVE
+
+/*
+ * Define if <sys/socket.h> exists.
+ */
+#define HAVE_SYS_SOCKET_H 1
+
+/*
+ * Define if the strlcpy() function exists on the system.
+ */
+#define HAVE_STRLCPY 1
+
+/*
+ * Define if the open_memstream() function exists on the system.
+ */
+/* #define HAVE_OPEN_MEMSTREAM 1 */
+
+/*
+ * Define if the BSD funopen() function exists on the system.
+ */
+#define HAVE_FUNOPEN 1
+
+/*
+ * Define if prctl() exists
+ */
+#define HAVE_PRCTL 1
+
+/*
+ * Define if writev() exists
+ */
+#define HAVE_WRITEV 1
+
+/*
+ * Define if <stdint.h> exists.
+ */
+#define HAVE_STDINT_H 1
+
+/*
+ * Define if <stdbool.h> exists.
+ */
+#define HAVE_STDBOOL_H 1
+
+/*
+ * Define if <sched.h> exists.
+ */
+#define HAVE_SCHED_H 1
+
+/*
+ * Define if pread() exists
+ */
+#define HAVE_PREAD 1
+
+/*
+ * Define if we have st_mtim in struct stat
+ */
+#define HAVE_STAT_ST_MTIM 1
+
+/*
+ * Define if printf() supports %zd for size_t arguments
+ */
+#define HAVE_PRINTF_ZD 1
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a BSD style function prototype.
+ */
+#define HAVE_BSD_QSORT_R 0
+
+/*
+ * Define to 1 if <stdlib.h> provides qsort_r() with a GNU style function prototype.
+ */
+#define HAVE_GNU_QSORT_R 0
+
+#endif /* _ANDROID_CONFIG_H */
diff --git a/core/config.mk b/core/config.mk
index 96993c0..b6111f2 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -267,6 +267,37 @@
 TARGET_TOOLCHAIN_ROOT := $(wildcard $(TARGET_TOOLCHAIN_ROOT))
 endif
 
+# Normalize WITH_STATIC_ANALYZER and WITH_SYNTAX_CHECK
+ifeq ($(strip $(WITH_STATIC_ANALYZER)),0)
+  WITH_STATIC_ANALYZER :=
+endif
+ifeq ($(strip $(WITH_SYNTAX_CHECK)),0)
+  WITH_SYNTAX_CHECK :=
+endif
+
+# Disable WITH_STATIC_ANALYZER and WITH_SYNTAX_CHECK if tool can't be found
+SYNTAX_TOOLS_PREFIX := prebuilts/clang/$(HOST_PREBUILT_TAG)/host/3.3/bin
+ifneq ($(strip $(WITH_STATIC_ANALYZER)),)
+  ifeq ($(wildcard $(SYNTAX_TOOLS_PREFIX)/ccc-analyzer),)
+    $(warning *** Disable WITH_STATIC_ANALYZER because $(SYNTAX_TOOLS_PREFIX)/ccc-analyzer does not exist)
+    WITH_STATIC_ANALYZER :=
+  endif
+endif
+ifneq ($(strip $(WITH_SYNTAX_CHECK)),)
+  ifeq ($(wildcard $(SYNTAX_TOOLS_PREFIX)/ccc-syntax),)
+    $(warning *** Disable WITH_SYNTAX_CHECK because $(SYNTAX_TOOLS_PREFIX)/ccc-syntax does not exist)
+    WITH_SYNTAX_CHECK :=
+  endif
+endif
+
+# WITH_STATIC_ANALYZER trumps WITH_SYNTAX_CHECK
+ifneq ($(strip $(WITH_STATIC_ANALYZER)),)
+  ifneq ($(strip $(WITH_SYNTAX_CHECK)),)
+    $(warning *** Disable WITH_SYNTAX_CHECK in the presence of static analyzer WITH_STATIC_ANALYZER)
+    WITH_SYNTAX_CHECK :=
+  endif
+endif
+
 # Pick a Java compiler.
 include $(BUILD_SYSTEM)/combo/javac.mk
 
@@ -311,7 +342,11 @@
 SIGNAPK_JAR := $(HOST_OUT_JAVA_LIBRARIES)/signapk$(COMMON_JAVA_PACKAGE_SUFFIX)
 MKBOOTFS := $(HOST_OUT_EXECUTABLES)/mkbootfs$(HOST_EXECUTABLE_SUFFIX)
 MINIGZIP := $(HOST_OUT_EXECUTABLES)/minigzip$(HOST_EXECUTABLE_SUFFIX)
+ifeq (,$(strip $(BOARD_CUSTOM_MKBOOTIMG)))
 MKBOOTIMG := $(HOST_OUT_EXECUTABLES)/mkbootimg$(HOST_EXECUTABLE_SUFFIX)
+else
+MKBOOTIMG := $(BOARD_CUSTOM_MKBOOTIMG)
+endif
 MKYAFFS2 := $(HOST_OUT_EXECUTABLES)/mkyaffs2image$(HOST_EXECUTABLE_SUFFIX)
 APICHECK := $(HOST_OUT_EXECUTABLES)/apicheck$(HOST_EXECUTABLE_SUFFIX)
 FS_GET_STATS := $(HOST_OUT_EXECUTABLES)/fs_get_stats$(HOST_EXECUTABLE_SUFFIX)
diff --git a/core/dumpvar.mk b/core/dumpvar.mk
index 92bf6af..2612e06 100644
--- a/core/dumpvar.mk
+++ b/core/dumpvar.mk
@@ -22,9 +22,9 @@
 else ifeq ($(TARGET_ARCH),x86)
 
 # Add the x86 toolchain bin dir if it actually exists
-    ifneq ($(wildcard $(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/i686-linux-android-$(TARGET_GCC_VERSION)/bin),)
+    ifneq ($(wildcard $(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/x86_64-linux-android-$(TARGET_GCC_VERSION)/bin),)
         # this should be copied to HOST_OUT_EXECUTABLES instead
-        ABP:=$(ABP):$(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/i686-linux-android-$(TARGET_GCC_VERSION)/bin
+        ABP:=$(ABP):$(PWD)/prebuilts/gcc/$(HOST_PREBUILT_TAG)/x86/x86_64-linux-android-$(TARGET_GCC_VERSION)/bin
     endif
 endif
 
diff --git a/core/llvm_config.mk b/core/llvm_config.mk
index 18e689e..b870558 100644
--- a/core/llvm_config.mk
+++ b/core/llvm_config.mk
@@ -72,17 +72,34 @@
   CLANG_CONFIG_EXTRA_ASFLAGS += \
     -target i686-linux-android \
     -nostdlibinc \
-    -B$(TARGET_TOOLCHAIN_ROOT)/i686-linux-android/bin
+    -B$(TARGET_TOOLCHAIN_ROOT)/x86_64-linux-android/bin
   CLANG_CONFIG_EXTRA_CFLAGS += $(CLANG_CONFIG_EXTRA_ASFLAGS)
   CLANG_CONFIG_EXTRA_LDFLAGS += \
     -target i686-linux-android \
-    -B$(TARGET_TOOLCHAIN_ROOT)/i686-linux-android/bin
+    -B$(TARGET_TOOLCHAIN_ROOT)/x86_64-linux-android/bin
   CLANG_CONFIG_UNKNOWN_CFLAGS += \
     -finline-limit=300 \
     -fno-inline-functions-called-once \
     -mfpmath=sse \
     -mbionic
 endif
+ifeq ($(TARGET_ARCH),x86_64)
+  RS_TRIPLE := x86_64-unknown-linux
+  CLANG_CONFIG_EXTRA_ASFLAGS += \
+    -target x86_64-linux-android \
+    -nostdlibinc \
+    -B$(TARGET_TOOLCHAIN_ROOT)/x86_64-linux-android/bin
+  CLANG_CONFIG_EXTRA_CFLAGS += $(CLANG_CONFIG_EXTRA_ASFLAGS)
+  CLANG_CONFIG_EXTRA_LDFLAGS += \
+    -target x86_64-linux-android \
+    -B$(TARGET_TOOLCHAIN_ROOT)/x86_64-linux-android/bin
+  CLANG_CONFIG_UNKNOWN_CFLAGS += \
+    -finline-limit=300 \
+    -fno-inline-functions-called-once \
+    -mfpmath=sse \
+    -mbionic
+endif
+
 
 CLANG_CONFIG_EXTRA_TARGET_C_INCLUDES := external/clang/lib/include $(TARGET_OUT_HEADERS)/clang
 
@@ -97,9 +114,11 @@
 $(call clang-flags-subst,-march=armv5te,-march=armv5t)
 $(call clang-flags-subst,-march=armv5e,-march=armv5)
 
-# clang does not support -Wno-psabi and -Wno-unused-but-set-variable
+# clang does not support -Wno-psabi, -Wno-unused-but-set-variable, and
+# -Wno-unused-but-set-parameter
 $(call clang-flags-subst,-Wno-psabi,)
 $(call clang-flags-subst,-Wno-unused-but-set-variable,)
+$(call clang-flags-subst,-Wno-unused-but-set-parameter,)
 
 # clang does not support -mcpu=cortex-a15 yet - fall back to armv7-a for now
 $(call clang-flags-subst,-mcpu=cortex-a15,-march=armv7-a)
diff --git a/core/prebuilt.mk b/core/prebuilt.mk
index 3e73c8d..e34fa55 100644
--- a/core/prebuilt.mk
+++ b/core/prebuilt.mk
@@ -190,3 +190,5 @@
 # make sure the classes.jar and javalib.jar are built before $(LOCAL_BUILT_MODULE)
 $(built_module) : $(common_javalib_jar)
 endif # TARGET JAVA_LIBRARIES
+
+$(built_module) : $(LOCAL_ADDITIONAL_DEPENDENCIES)
diff --git a/core/tasks/cts.mk b/core/tasks/cts.mk
index f38f090..ed8c125 100644
--- a/core/tasks/cts.mk
+++ b/core/tasks/cts.mk
@@ -76,7 +76,7 @@
 @echo "Generate core-test description ("$(notdir $(1))")"
 $(hide) java -Xmx256M \
 	-Xbootclasspath/a:$(PRIVATE_CLASSPATH) \
-	-classpath $(PRIVATE_CLASSPATH):$(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_JDK_TOOLS_JAR) \
+	-classpath $(PRIVATE_CLASSPATH):$(HOST_OUT_JAVA_LIBRARIES)/descGen.jar:$(HOST_OUT_JAVA_LIBRARIES)/junit.jar:$(HOST_JDK_TOOLS_JAR) \
 	$(PRIVATE_PARAMS) CollectAllTests $(1) $(2) $(3) "$(4)" $(5) $(6)
 endef
 
@@ -107,7 +107,7 @@
 # build system requires that dependencies use javalib.jar.  If
 # javalib.jar is up-to-date, then classes.jar is as well.  Depending
 # on classes.jar will build the files incorrectly.
-CTS_CORE_XMLS_DEPS := $(CTS_CORE_CASES) $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(CORE_INTERMEDIATES)/javalib.jar $(BOUNCYCASTLE_INTERMEDIATES)/javalib.jar $(APACHEXML_INTERMEDIATES)/javalib.jar $(OKHTTP_INTERMEDIATES)/javalib.jar $(SQLITEJDBC_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(CORETESTS_INTERMEDIATES)/javalib.jar $(CONSCRYPTTESTS_INTERMEDIATES)/javalib.jar | $(ACP)
+CTS_CORE_XMLS_DEPS := $(CTS_CORE_CASES) $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(HOST_OUT_JAVA_LIBRARIES)/junit.jar $(CORE_INTERMEDIATES)/javalib.jar $(BOUNCYCASTLE_INTERMEDIATES)/javalib.jar $(APACHEXML_INTERMEDIATES)/javalib.jar $(OKHTTP_INTERMEDIATES)/javalib.jar $(SQLITEJDBC_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(CORETESTS_INTERMEDIATES)/javalib.jar $(CONSCRYPTTESTS_INTERMEDIATES)/javalib.jar | $(ACP)
 
 $(CTS_TESTCASES_OUT)/android.core.tests.libcore.package.dalvik.xml: $(CTS_CORE_XMLS_DEPS)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
@@ -170,7 +170,7 @@
 
 $(CORE_VM_TEST_TF_DESC): PRIVATE_CLASSPATH:=$(GEN_CLASSPATH)
 # Please see big comment above on why this line depends on javalib.jar instead of classes.jar
-$(CORE_VM_TEST_TF_DESC): $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(CORE_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(VMTESTSTF_JAR) $(DDMLIB_JAR) | $(ACP)
+$(CORE_VM_TEST_TF_DESC): $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(HOST_OUT_JAVA_LIBRARIES)/junit.jar $(CORE_INTERMEDIATES)/javalib.jar $(JUNIT_INTERMEDIATES)/javalib.jar $(VMTESTSTF_JAR) $(DDMLIB_JAR) | $(ACP)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(call generate-core-test-description,$(CTS_TESTCASES_OUT)/android.core.vm-tests-tf,\
 		cts/tests/vm-tests-tf/AndroidManifest.xml,\
diff --git a/envsetup.sh b/envsetup.sh
index 0661fe6..33d73f1 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -126,10 +126,14 @@
     export ANDROID_EABI_TOOLCHAIN=
     local ARCH=$(get_build_var TARGET_ARCH)
     case $ARCH in
-        x86) toolchaindir=x86/i686-linux-android-$targetgccversion/bin
+        x86) toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin
+            ;;
+        x86_64) toolchaindir=x86/x86_64-linux-android-$targetgccversion/bin
             ;;
         arm) toolchaindir=arm/arm-linux-androideabi-$targetgccversion/bin
             ;;
+        aarch64) toolchaindir=aarch64/aarch64-linux-android-$targetgccversion/bin
+            ;;
         mips) toolchaindir=mips/mipsel-linux-android-$targetgccversion/bin
             ;;
         *)
@@ -205,6 +209,8 @@
     set_sequence_number
 
     export ANDROID_BUILD_TOP=$(gettop)
+    # With this environment variable new GCC can apply colors to warnings/errors
+    export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
 }
 
 function set_sequence_number()
@@ -429,6 +435,7 @@
 add_lunch_combo aosp_arm-eng
 add_lunch_combo aosp_x86-eng
 add_lunch_combo aosp_mips-eng
+add_lunch_combo aosp_x86_64-eng
 add_lunch_combo vbox_x86-eng
 
 function print_lunch_menu()
@@ -601,11 +608,26 @@
     fi
 }
 
+# Return driver for "make", if any (eg. static analyzer)
+function getdriver()
+{
+    local T="$1"
+    test "$WITH_STATIC_ANALYZER" = "0" && unset WITH_STATIC_ANALYZER
+    if [ -n "$WITH_STATIC_ANALYZER" ]; then
+        echo "\
+$T/prebuilts/clang/linux-x86/host/3.3/tools/scan-build/scan-build \
+--use-analyzer $T/prebuilts/clang/linux-x86/host/3.3/bin/analyzer \
+--status-bugs \
+--top=$T"
+    fi
+}
+
 function m()
 {
-    T=$(gettop)
+    local T=$(gettop)
+    local DRV=$(getdriver $T)
     if [ "$T" ]; then
-        make -C $T -f build/core/main.mk $@
+        $DRV make -C $T -f build/core/main.mk $@
     else
         echo "Couldn't locate the top of the tree.  Try setting TOP."
     fi
@@ -630,13 +652,14 @@
 
 function mm()
 {
+    local T=$(gettop)
+    local DRV=$(getdriver $T)
     # If we're sitting in the root of the build tree, just do a
     # normal make.
     if [ -f build/core/envsetup.mk -a -f Makefile ]; then
-        make $@
+        $DRV make $@
     else
         # Find the closest Android.mk file.
-        T=$(gettop)
         local M=$(findmakefile)
         local MODULES=
         local GET_INSTALL_PATH=
@@ -660,14 +683,15 @@
               MODULES=all_modules
               ARGS=$@
             fi
-            ONE_SHOT_MAKEFILE=$M make -C $T -f build/core/main.mk $MODULES $ARGS
+            ONE_SHOT_MAKEFILE=$M $DRV make -C $T -f build/core/main.mk $MODULES $ARGS
         fi
     fi
 }
 
 function mmm()
 {
-    T=$(gettop)
+    local T=$(gettop)
+    local DRV=$(getdriver $T)
     if [ "$T" ]; then
         local MAKEFILE=
         local MODULES=
@@ -705,7 +729,7 @@
           ARGS=$GET_INSTALL_PATH
           MODULES=
         fi
-        ONE_SHOT_MAKEFILE="$MAKEFILE" make -C $T -f build/core/main.mk $DASH_ARGS $MODULES $ARGS
+        ONE_SHOT_MAKEFILE="$MAKEFILE" $DRV make -C $T -f build/core/main.mk $DASH_ARGS $MODULES $ARGS
     else
         echo "Couldn't locate the top of the tree.  Try setting TOP."
     fi
@@ -713,21 +737,23 @@
 
 function mma()
 {
+  local T=$(gettop)
+  local DRV=$(getdriver $T)
   if [ -f build/core/envsetup.mk -a -f Makefile ]; then
-    make $@
+    $DRV make $@
   else
-    T=$(gettop)
     if [ ! "$T" ]; then
       echo "Couldn't locate the top of the tree.  Try setting TOP."
     fi
     local MY_PWD=`PWD= /bin/pwd|sed 's:'$T'/::'`
-    make -C $T -f build/core/main.mk $@ all_modules BUILD_MODULES_IN_PATHS="$MY_PWD"
+    $DRV make -C $T -f build/core/main.mk $@ all_modules BUILD_MODULES_IN_PATHS="$MY_PWD"
   fi
 }
 
 function mmma()
 {
-  T=$(gettop)
+  local T=$(gettop)
+  local DRV=$(getdriver $T)
   if [ "$T" ]; then
     local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')
     local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')
@@ -754,7 +780,7 @@
         esac
       fi
     done
-    make -C $T -f build/core/main.mk $DASH_ARGS $ARGS all_modules BUILD_MODULES_IN_PATHS="$MODULE_PATHS"
+    $DRV make -C $T -f build/core/main.mk $DASH_ARGS $ARGS all_modules BUILD_MODULES_IN_PATHS="$MODULE_PATHS"
   else
     echo "Couldn't locate the top of the tree.  Try setting TOP."
   fi
@@ -902,7 +928,7 @@
    local ARCH=$(get_build_var TARGET_ARCH)
    local GDB
    case "$ARCH" in
-       x86) GDB=i686-linux-android-gdb;;
+       x86) GDB=x86_64-linux-android-gdb;;
        arm) GDB=arm-linux-androideabi-gdb;;
        mips) GDB=mipsel-linux-android-gdb;;
        *) echo "Unknown arch $ARCH"; return 1;;
diff --git a/target/board/generic_aarch64/BoardConfig.mk b/target/board/generic_aarch64/BoardConfig.mk
new file mode 100644
index 0000000..b4dfa97
--- /dev/null
+++ b/target/board/generic_aarch64/BoardConfig.mk
@@ -0,0 +1,53 @@
+# Copyright (C) 2013 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.
+#
+
+# The generic product target doesn't have any hardware-specific pieces.
+TARGET_NO_BOOTLOADER := true
+TARGET_NO_KERNEL := true
+TARGET_ARCH := aarch64
+TARGET_ARCH_VARIANT := armv8-a
+TARGET_CPU_VARIANT := generic
+TARGET_CPU_ABI := aarch64-v8a
+
+# no hardware camera
+USE_CAMERA_STUB := true
+
+# Enable dex-preoptimization to speed up the first boot sequence
+# of an SDK AVD. Note that this operation only works on Linux for now
+ifeq ($(HOST_OS),linux)
+  ifeq ($(WITH_DEXPREOPT),)
+    WITH_DEXPREOPT := true
+  endif
+endif
+
+# Build OpenGLES emulation host and guest libraries
+BUILD_EMULATOR_OPENGL := true
+
+# Build and enable the OpenGL ES View renderer. When running on the emulator,
+# the GLES renderer disables itself if host GL acceleration isn't available.
+USE_OPENGL_RENDERER := true
+
+TARGET_USERIMAGES_USE_EXT4 := true
+BOARD_SYSTEMIMAGE_PARTITION_SIZE := 576716800
+BOARD_USERDATAIMAGE_PARTITION_SIZE := 209715200
+BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
+BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
+BOARD_FLASH_BLOCK_SIZE := 512
+TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
+
+# FIXME
+# Temporarily disable linking against compiler_rt until there is an aarch64
+# version
+WITHOUT_LIBCOMPILER_RT := true
diff --git a/target/board/generic_aarch64/README.txt b/target/board/generic_aarch64/README.txt
new file mode 100644
index 0000000..681c31e
--- /dev/null
+++ b/target/board/generic_aarch64/README.txt
@@ -0,0 +1,5 @@
+The "generic_aarch64" product defines a non-hardware-specific aarch64 target
+without a kernel or bootloader.
+
+It is not a product "base class"; no other products inherit
+from it or use it in any way.
diff --git a/target/board/generic_aarch64/device.mk b/target/board/generic_aarch64/device.mk
new file mode 100644
index 0000000..8582e5b
--- /dev/null
+++ b/target/board/generic_aarch64/device.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2013 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 is a build configuration for the product aspects that
+# are specific to the emulator.
+
+PRODUCT_PROPERTY_OVERRIDES := \
+    ro.ril.hsxpa=1 \
+    ro.ril.gprsclass=10 \
+    ro.adb.qemud=1
+
+PRODUCT_COPY_FILES := \
+    device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
+    device/generic/goldfish/camera/media_profiles.xml:system/etc/media_profiles.xml \
+    device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml
+
+PRODUCT_PACKAGES := \
+    audio.primary.goldfish
diff --git a/target/board/generic_aarch64/system.prop b/target/board/generic_aarch64/system.prop
new file mode 100644
index 0000000..29e4be9
--- /dev/null
+++ b/target/board/generic_aarch64/system.prop
@@ -0,0 +1,6 @@
+#
+# system.prop for generic aarch64 sdk
+#
+
+rild.libpath=/system/lib/libreference-ril.so
+rild.libargs=-d /dev/ttyS0
diff --git a/target/board/generic_x86_64/BoardConfig.mk b/target/board/generic_x86_64/BoardConfig.mk
new file mode 100755
index 0000000..8a2fd13
--- /dev/null
+++ b/target/board/generic_x86_64/BoardConfig.mk
@@ -0,0 +1,43 @@
+# config.mk
+#
+# Product-specific compile-time definitions.
+#
+
+# The generic product target doesn't have any hardware-specific pieces.
+TARGET_NO_BOOTLOADER := true
+TARGET_NO_KERNEL := true
+TARGET_CPU_ABI := x86_64
+TARGET_ARCH := x86_64
+TARGET_ARCH_VARIANT := x86_64
+TARGET_PRELINK_MODULE := false
+
+# The IA emulator (qemu) uses the Goldfish devices
+HAVE_HTC_AUDIO_DRIVER := true
+BOARD_USES_GENERIC_AUDIO := true
+
+# no hardware camera
+USE_CAMERA_STUB := true
+
+# customize the malloced address to be 16-byte aligned
+BOARD_MALLOC_ALIGNMENT := 16
+
+# Enable dex-preoptimization to speed up the first boot sequence
+# of an SDK AVD. Note that this operation only works on Linux for now
+ifeq ($(HOST_OS),linux)
+WITH_DEXPREOPT := true
+endif
+
+# Build OpenGLES emulation host and guest libraries
+BUILD_EMULATOR_OPENGL := true
+
+# Build and enable the OpenGL ES View renderer. When running on the emulator,
+# the GLES renderer disables itself if host GL acceleration isn't available.
+USE_OPENGL_RENDERER := true
+
+TARGET_USERIMAGES_USE_EXT4 := true
+BOARD_SYSTEMIMAGE_PARTITION_SIZE := 576716800
+BOARD_USERDATAIMAGE_PARTITION_SIZE := 209715200
+BOARD_CACHEIMAGE_PARTITION_SIZE := 69206016
+BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
+BOARD_FLASH_BLOCK_SIZE := 512
+TARGET_USERIMAGES_SPARSE_EXT_DISABLED := true
diff --git a/target/board/generic_x86_64/README.txt b/target/board/generic_x86_64/README.txt
new file mode 100644
index 0000000..46b015b
--- /dev/null
+++ b/target/board/generic_x86_64/README.txt
@@ -0,0 +1,8 @@
+The "generic_x86_64" product defines a non-hardware-specific IA target
+without a kernel or bootloader.
+
+It can be used to build the entire user-level system, and
+will work with the IA version of the emulator,
+
+It is not a product "base class"; no other products inherit
+from it or use it in any way.
diff --git a/target/board/generic_x86_64/device.mk b/target/board/generic_x86_64/device.mk
new file mode 100755
index 0000000..574ce4f
--- /dev/null
+++ b/target/board/generic_x86_64/device.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2009 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 is a build configuration for the product aspects that
+# are specific to the emulator.
+
+PRODUCT_PROPERTY_OVERRIDES := \
+    ro.ril.hsxpa=1 \
+    ro.ril.gprsclass=10 \
+    ro.adb.qemud=1
+
+PRODUCT_COPY_FILES := \
+    device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml \
+    device/generic/goldfish/camera/media_profiles.xml:system/etc/media_profiles.xml \
+    device/generic/goldfish/camera/media_codecs.xml:system/etc/media_codecs.xml
+
+PRODUCT_PACKAGES := \
+    audio.primary.goldfish
diff --git a/target/board/generic_x86_64/system.prop b/target/board/generic_x86_64/system.prop
new file mode 100644
index 0000000..137a0f9
--- /dev/null
+++ b/target/board/generic_x86_64/system.prop
@@ -0,0 +1,6 @@
+#
+# system.prop for generic sdk
+#
+
+rild.libpath=/system/lib/libreference-ril.so
+rild.libargs=-d /dev/ttyS0
diff --git a/target/product/AndroidProducts.mk b/target/product/AndroidProducts.mk
index a72d2f3..e3298a9 100644
--- a/target/product/AndroidProducts.mk
+++ b/target/product/AndroidProducts.mk
@@ -40,7 +40,8 @@
     $(LOCAL_DIR)/aosp_x86.mk \
     $(LOCAL_DIR)/full_x86.mk \
     $(LOCAL_DIR)/aosp_mips.mk \
-    $(LOCAL_DIR)/full_mips.mk
+    $(LOCAL_DIR)/full_mips.mk \
+    $(LOCAL_DIR)/aosp_aarch64.mk
 else
 PRODUCT_MAKEFILES := \
     $(LOCAL_DIR)/core.mk \
@@ -53,6 +54,9 @@
     $(LOCAL_DIR)/full_x86.mk \
     $(LOCAL_DIR)/aosp_mips.mk \
     $(LOCAL_DIR)/full_mips.mk \
+    $(LOCAL_DIR)/aosp_aarch64.mk \
+    $(LOCAL_DIR)/aosp_x86_64.mk \
+    $(LOCAL_DIR)/full_x86_64.mk \
     $(LOCAL_DIR)/vbox_x86.mk \
     $(LOCAL_DIR)/sdk.mk \
     $(LOCAL_DIR)/sdk_x86.mk \
diff --git a/target/product/aosp_aarch64.mk b/target/product/aosp_aarch64.mk
new file mode 100644
index 0000000..67b7dde
--- /dev/null
+++ b/target/product/aosp_aarch64.mk
@@ -0,0 +1,29 @@
+#
+# Copyright (C) 2013 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 is a build configuration for a full-featured build of the
+# Open-Source part of the tree. It's geared toward a US-centric
+# build quite specifically for the emulator, and might not be
+# entirely appropriate to inherit from for on-device configurations.
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_aarch64/device.mk)
+
+include $(SRC_TARGET_DIR)/product/emulator.mk
+PRODUCT_NAME := aosp_aarch64
+PRODUCT_DEVICE := generic_aarch64
+PRODUCT_BRAND := Android
+PRODUCT_MODEL := AOSP on ARM aarch64 Emulator
diff --git a/target/product/aosp_x86_64.mk b/target/product/aosp_x86_64.mk
new file mode 100644
index 0000000..5a12c08
--- /dev/null
+++ b/target/product/aosp_x86_64.mk
@@ -0,0 +1,18 @@
+#
+# Copyright 2013 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.
+#
+$(call inherit-product, $(SRC_TARGET_DIR)/product/full_x86_64.mk)
+
+PRODUCT_NAME := aosp_x86_64
diff --git a/target/product/full_x86_64.mk b/target/product/full_x86_64.mk
new file mode 100755
index 0000000..644f2a2
--- /dev/null
+++ b/target/product/full_x86_64.mk
@@ -0,0 +1,44 @@
+#
+# Copyright (C) 2009 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 is a build configuration for a full-featured build of the
+# Open-Source part of the tree. It's geared toward a US-centric
+# build quite specifically for the emulator, and might not be
+# entirely appropriate to inherit from for on-device configurations.
+
+# If running on an emulator or some other device that has a LAN connection
+# that isn't a wifi connection. This will instruct init.rc to enable the
+# network connection so that you can use it with ADB
+
+$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_x86_64/device.mk)
+
+include $(SRC_TARGET_DIR)/product/emulator.mk
+
+ifdef NET_ETH0_STARTONBOOT
+  PRODUCT_PROPERTY_OVERRIDES += net.eth0.startonboot=1
+endif
+
+# Ensure we package the BIOS files too.
+PRODUCT_PACKAGES += \
+	bios.bin \
+	vgabios-cirrus.bin \
+
+# Overrides
+PRODUCT_NAME := full_x86_64
+PRODUCT_DEVICE := generic_x86_64
+PRODUCT_BRAND := Android
+PRODUCT_MODEL := AOSP on IA x86_64 Emulator
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index 817d9a4..bc59782 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -90,6 +90,7 @@
 
 include $(SRC_TARGET_DIR)/product/emulator.mk
 
+$(call inherit-product-if-exists, frameworks/base/data/sounds/AllAudio.mk)
 $(call inherit-product-if-exists, frameworks/base/data/fonts/fonts.mk)
 $(call inherit-product-if-exists, frameworks/base/data/keyboards/keyboards.mk)
 $(call inherit-product-if-exists, frameworks/webview/chromium/chromium.mk)
diff --git a/tools/releasetools/check_target_files_signatures b/tools/releasetools/check_target_files_signatures
index ae372ba..45d30a6 100755
--- a/tools/releasetools/check_target_files_signatures
+++ b/tools/releasetools/check_target_files_signatures
@@ -135,7 +135,7 @@
 
     for i in to_load:
       f = open(i)
-      cert = ParseCertificate(f.read())
+      cert = common.ParseCertificate(f.read())
       f.close()
       name, _ = os.path.splitext(i)
       name, _ = os.path.splitext(name)
@@ -144,21 +144,6 @@
 ALL_CERTS = CertDB()
 
 
-def ParseCertificate(data):
-  """Parse a PEM-format certificate."""
-  cert = []
-  save = False
-  for line in data.split("\n"):
-    if "--END CERTIFICATE--" in line:
-      break
-    if save:
-      cert.append(line)
-    if "--BEGIN CERTIFICATE--" in line:
-      save = True
-  cert = "".join(cert).decode('base64')
-  return cert
-
-
 def CertFromPKCS7(data, filename):
   """Read the cert out of a PKCS#7-format file (which is what is
   stored in a signed .apk)."""
@@ -175,7 +160,7 @@
       AddProblem("error reading cert:\n" + err)
       return None
 
-    cert = ParseCertificate(out)
+    cert = common.ParseCertificate(out)
     if not cert:
       AddProblem("error parsing cert output")
       return None
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 58582ba..f179717 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -287,7 +287,10 @@
   assert p1.returncode == 0, "mkbootfs of %s ramdisk failed" % (targetname,)
   assert p2.returncode == 0, "minigzip of %s ramdisk failed" % (targetname,)
 
-  cmd = ["mkbootimg", "--kernel", os.path.join(sourcedir, "kernel")]
+  # use MKBOOTIMG from environ, or "mkbootimg" if empty or not set
+  mkbootimg = os.getenv('MKBOOTIMG') or "mkbootimg"
+
+  cmd = [mkbootimg, "--kernel", os.path.join(sourcedir, "kernel")]
 
   fn = os.path.join(sourcedir, "cmdline")
   if os.access(fn, os.F_OK):
@@ -306,7 +309,7 @@
 
   args = info_dict.get("mkbootimg_args", None)
   if args and args.strip():
-    cmd.extend(args.split())
+    cmd.extend(shlex.split(args))
 
   cmd.extend(["--ramdisk", ramdisk_img.name,
               "--output", img.name])
@@ -954,3 +957,18 @@
     return PARTITION_TYPES[fstab[mount_point].fs_type], fstab[mount_point].device
   else:
     return None
+
+
+def ParseCertificate(data):
+  """Parse a PEM-format certificate."""
+  cert = []
+  save = False
+  for line in data.split("\n"):
+    if "--END CERTIFICATE--" in line:
+      break
+    if save:
+      cert.append(line)
+    if "--BEGIN CERTIFICATE--" in line:
+      save = True
+  cert = "".join(cert).decode('base64')
+  return cert
diff --git a/tools/releasetools/sign_target_files_apks b/tools/releasetools/sign_target_files_apks
index 5556573..00693b8 100755
--- a/tools/releasetools/sign_target_files_apks
+++ b/tools/releasetools/sign_target_files_apks
@@ -71,8 +71,10 @@
   print >> sys.stderr, "Python 2.4 or newer is required."
   sys.exit(1)
 
+import base64
 import cStringIO
 import copy
+import errno
 import os
 import re
 import subprocess
@@ -161,11 +163,45 @@
       print "rewriting %s:" % (info.filename,)
       new_data = RewriteProps(data)
       output_tf_zip.writestr(out_info, 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)
     else:
       # a non-APK file; copy it verbatim
       output_tf_zip.writestr(out_info, data)
 
 
+def ReplaceCerts(data):
+  """Given a string of data, replace all occurences of a set
+  of X509 certs with a newer set of X509 certs and return
+  the updated data string."""
+  for old, new in OPTIONS.key_map.iteritems():
+    try:
+      if OPTIONS.verbose:
+        print "    Replacing %s.x509.pem with %s.x509.pem" % (old, new)
+      f = open(old + ".x509.pem")
+      old_cert16 = base64.b16encode(common.ParseCertificate(f.read())).lower()
+      f.close()
+      f = open(new + ".x509.pem")
+      new_cert16 = base64.b16encode(common.ParseCertificate(f.read())).lower()
+      f.close()
+      # Only match entire certs.
+      pattern = "\\b"+old_cert16+"\\b"
+      (data, num) = re.subn(pattern, new_cert16, data, flags=re.IGNORECASE)
+      if OPTIONS.verbose:
+        print "    Replaced %d occurence(s) of %s.x509.pem with " \
+            "%s.x509.pem" % (num, old, new)
+    except IOError, e:
+      if (e.errno == errno.ENOENT and not OPTIONS.verbose):
+        continue
+
+      print "    Error accessing %s. %s. Skip replacing %s.x509.pem " \
+          "with %s.x509.pem." % (e.filename, e.strerror, old, new)
+
+  return data
+
+
 def EditTags(tags):
   """Given a string containing comma-separated tags, apply the edits
   specified in OPTIONS.tag_changes and return the updated string."""
diff --git a/tools/signapk/SignApk.java b/tools/signapk/SignApk.java
index 716ea3b..b247072 100644
--- a/tools/signapk/SignApk.java
+++ b/tools/signapk/SignApk.java
@@ -20,6 +20,7 @@
 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
 import org.bouncycastle.asn1.DEROutputStream;
 import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
 import org.bouncycastle.cert.jcajce.JcaCertStore;
 import org.bouncycastle.cms.CMSException;
 import org.bouncycastle.cms.CMSProcessableByteArray;
@@ -35,7 +36,7 @@
 import org.bouncycastle.util.encoders.Base64;
 
 import java.io.BufferedReader;
-import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.File;
@@ -47,6 +48,7 @@
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintStream;
+import java.lang.reflect.Constructor;
 import java.security.DigestOutputStream;
 import java.security.GeneralSecurityException;
 import java.security.Key;
@@ -59,11 +61,11 @@
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
+import java.util.Locale;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.jar.Attributes;
@@ -83,9 +85,9 @@
  * Prior to the keylimepie release, SignApk ignored the signature
  * algorithm specified in the certificate and always used SHA1withRSA.
  *
- * Starting with keylimepie, we support SHA256withRSA, and use the
- * signature algorithm in the certificate to select which to use
- * (SHA256withRSA or SHA1withRSA).
+ * Starting with JB-MR2, the platform supports SHA256withRSA, so we use
+ * the signature algorithm in the certificate to select which to use
+ * (SHA256withRSA or SHA1withRSA). Also in JB-MR2, EC keys are supported.
  *
  * Because there are old keys still in use whose certificate actually
  * says "MD5withRSA", we treat these as though they say "SHA1withRSA"
@@ -95,15 +97,15 @@
 
 
 /**
- * Command line tool to sign JAR files (including APKs and OTA
- * updates) in a way compatible with the mincrypt verifier, using RSA
- * keys and SHA1 or SHA-256.
+ * Command line tool to sign JAR files (including APKs and OTA updates) in a way
+ * compatible with the mincrypt verifier, using EC or RSA keys and SHA1 or
+ * SHA-256 (see historical note).
  */
 class SignApk {
     private static final String CERT_SF_NAME = "META-INF/CERT.SF";
-    private static final String CERT_RSA_NAME = "META-INF/CERT.RSA";
+    private static final String CERT_SIG_NAME = "META-INF/CERT.%s";
     private static final String CERT_SF_MULTI_NAME = "META-INF/CERT%d.SF";
-    private static final String CERT_RSA_MULTI_NAME = "META-INF/CERT%d.RSA";
+    private static final String CERT_SIG_MULTI_NAME = "META-INF/CERT%d.%s";
 
     private static final String OTACERT_NAME = "META-INF/com/android/otacert";
 
@@ -117,12 +119,12 @@
      * Return one of USE_SHA1 or USE_SHA256 according to the signature
      * algorithm specified in the cert.
      */
-    private static int getAlgorithm(X509Certificate cert) {
-        String sigAlg = cert.getSigAlgName();
-        if ("SHA1withRSA".equals(sigAlg) ||
-            "MD5withRSA".equals(sigAlg)) {     // see "HISTORICAL NOTE" above.
+    private static int getDigestAlgorithm(X509Certificate cert) {
+        String sigAlg = cert.getSigAlgName().toUpperCase(Locale.US);
+        if ("SHA1WITHRSA".equals(sigAlg) ||
+            "MD5WITHRSA".equals(sigAlg)) {     // see "HISTORICAL NOTE" above.
             return USE_SHA1;
-        } else if ("SHA256withRSA".equals(sigAlg)) {
+        } else if (sigAlg.startsWith("SHA256WITH")) {
             return USE_SHA256;
         } else {
             throw new IllegalArgumentException("unsupported signature algorithm \"" + sigAlg +
@@ -130,9 +132,26 @@
         }
     }
 
+    /** Returns the expected signature algorithm for this key type. */
+    private static String getSignatureAlgorithm(X509Certificate cert) {
+        String sigAlg = cert.getSigAlgName().toUpperCase(Locale.US);
+        String keyType = cert.getPublicKey().getAlgorithm().toUpperCase(Locale.US);
+        if ("RSA".equalsIgnoreCase(keyType)) {
+            if (getDigestAlgorithm(cert) == USE_SHA256) {
+                return "SHA256withRSA";
+            } else {
+                return "SHA1withRSA";
+            }
+        } else if ("EC".equalsIgnoreCase(keyType)) {
+            return "SHA256withECDSA";
+        } else {
+            throw new IllegalArgumentException("unsupported key type: " + keyType);
+        }
+    }
+
     // Files matching this pattern are not copied to the output.
     private static Pattern stripPattern =
-        Pattern.compile("^(META-INF/((.*)[.](SF|RSA|DSA)|com/android/otacert))|(" +
+        Pattern.compile("^(META-INF/((.*)[.](SF|RSA|DSA|EC)|com/android/otacert))|(" +
                         Pattern.quote(JarFile.MANIFEST_NAME) + ")$");
 
     private static X509Certificate readPublicKey(File file)
@@ -164,7 +183,7 @@
     }
 
     /**
-     * Decrypt an encrypted PKCS 8 format private key.
+     * Decrypt an encrypted PKCS#8 format private key.
      *
      * Based on ghstark's post on Aug 6, 2006 at
      * http://forums.sun.com/thread.jspa?threadID=758133&messageID=4330949
@@ -172,7 +191,7 @@
      * @param encryptedPrivateKey The raw data of the private key
      * @param keyFile The file containing the private key
      */
-    private static KeySpec decryptPrivateKey(byte[] encryptedPrivateKey, File keyFile)
+    private static PKCS8EncodedKeySpec decryptPrivateKey(byte[] encryptedPrivateKey, File keyFile)
         throws GeneralSecurityException {
         EncryptedPrivateKeyInfo epkInfo;
         try {
@@ -198,7 +217,7 @@
         }
     }
 
-    /** Read a PKCS 8 format private key. */
+    /** Read a PKCS#8 format private key. */
     private static PrivateKey readPrivateKey(File file)
         throws IOException, GeneralSecurityException {
         DataInputStream input = new DataInputStream(new FileInputStream(file));
@@ -206,16 +225,21 @@
             byte[] bytes = new byte[(int) file.length()];
             input.read(bytes);
 
-            KeySpec spec = decryptPrivateKey(bytes, file);
+            /* Check to see if this is in an EncryptedPrivateKeyInfo structure. */
+            PKCS8EncodedKeySpec spec = decryptPrivateKey(bytes, file);
             if (spec == null) {
                 spec = new PKCS8EncodedKeySpec(bytes);
             }
 
-            try {
-                return KeyFactory.getInstance("RSA").generatePrivate(spec);
-            } catch (InvalidKeySpecException ex) {
-                return KeyFactory.getInstance("DSA").generatePrivate(spec);
-            }
+            /*
+             * Now it's in a PKCS#8 PrivateKeyInfo structure. Read its Algorithm
+             * OID and use that to construct a KeyFactory.
+             */
+            ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(spec.getEncoded()));
+            PrivateKeyInfo pki = PrivateKeyInfo.getInstance(bIn.readObject());
+            String algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId();
+
+            return KeyFactory.getInstance(algOid).generatePrivate(spec);
         } finally {
             input.close();
         }
@@ -413,8 +437,7 @@
         JcaCertStore certs = new JcaCertStore(certList);
 
         CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
-        ContentSigner signer = new JcaContentSignerBuilder(
-            getAlgorithm(publicKey) == USE_SHA256 ? "SHA256withRSA" : "SHA1withRSA")
+        ContentSigner signer = new JcaContentSignerBuilder(getSignatureAlgorithm(publicKey))
             .setProvider(sBouncyCastleProvider)
             .build(privateKey);
         gen.addSignerInfoGenerator(
@@ -560,7 +583,7 @@
                 signer = new WholeFileSignerOutputStream(out, outputStream);
                 JarOutputStream outputJar = new JarOutputStream(signer);
 
-                int hash = getAlgorithm(publicKey);
+                int hash = getDigestAlgorithm(publicKey);
 
                 // Assume the certificate is valid for at least an hour.
                 long timestamp = publicKey.getNotBefore().getTime() + 3600L * 1000;
@@ -685,13 +708,15 @@
             je.setTime(timestamp);
             outputJar.putNextEntry(je);
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            writeSignatureFile(manifest, baos, getAlgorithm(publicKey[k]));
+            writeSignatureFile(manifest, baos, getDigestAlgorithm(publicKey[k]));
             byte[] signedData = baos.toByteArray();
             outputJar.write(signedData);
 
-            // CERT.RSA / CERT#.RSA
-            je = new JarEntry(numKeys == 1 ? CERT_RSA_NAME :
-                              (String.format(CERT_RSA_MULTI_NAME, k)));
+            // CERT.{EC,RSA} / CERT#.{EC,RSA}
+            final String keyType = publicKey[k].getPublicKey().getAlgorithm();
+            je = new JarEntry(numKeys == 1 ?
+                              (String.format(CERT_SIG_NAME, keyType)) :
+                              (String.format(CERT_SIG_MULTI_NAME, k, keyType)));
             je.setTime(timestamp);
             outputJar.putNextEntry(je);
             writeSignatureBlock(new CMSProcessableByteArray(signedData),
@@ -699,8 +724,61 @@
         }
     }
 
+    /**
+     * Tries to load a JSE Provider by class name. This is for custom PrivateKey
+     * types that might be stored in PKCS#11-like storage.
+     */
+    private static void loadProviderIfNecessary(String providerClassName) {
+        if (providerClassName == null) {
+            return;
+        }
+
+        final Class<?> klass;
+        try {
+            final ClassLoader sysLoader = ClassLoader.getSystemClassLoader();
+            if (sysLoader != null) {
+                klass = sysLoader.loadClass(providerClassName);
+            } else {
+                klass = Class.forName(providerClassName);
+            }
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+            System.exit(1);
+            return;
+        }
+
+        Constructor<?> constructor = null;
+        for (Constructor<?> c : klass.getConstructors()) {
+            if (c.getParameterTypes().length == 0) {
+                constructor = c;
+                break;
+            }
+        }
+        if (constructor == null) {
+            System.err.println("No zero-arg constructor found for " + providerClassName);
+            System.exit(1);
+            return;
+        }
+
+        final Object o;
+        try {
+            o = constructor.newInstance();
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.exit(1);
+            return;
+        }
+        if (!(o instanceof Provider)) {
+            System.err.println("Not a Provider class: " + providerClassName);
+            System.exit(1);
+        }
+
+        Security.insertProviderAt((Provider) o, 1);
+    }
+
     private static void usage() {
         System.err.println("Usage: signapk [-w] " +
+                           "[-providerClass <className>] " +
                            "publickey.x509[.pem] privatekey.pk8 " +
                            "[publickey2.x509[.pem] privatekey2.pk8 ...] " +
                            "input.jar output.jar");
@@ -714,10 +792,23 @@
         Security.addProvider(sBouncyCastleProvider);
 
         boolean signWholeFile = false;
+        String providerClass = null;
+        String providerArg = null;
+
         int argstart = 0;
-        if (args[0].equals("-w")) {
-            signWholeFile = true;
-            argstart = 1;
+        while (argstart < args.length && args[argstart].startsWith("-")) {
+            if ("-w".equals(args[argstart])) {
+                signWholeFile = true;
+                ++argstart;
+            } else if ("-providerClass".equals(args[argstart])) {
+                if (argstart + 1 >= args.length) {
+                    usage();
+                }
+                providerClass = args[++argstart];
+                ++argstart;
+            } else {
+                usage();
+            }
         }
 
         if ((args.length - argstart) % 2 == 1) usage();
@@ -727,6 +818,8 @@
             System.exit(2);
         }
 
+        loadProviderIfNecessary(providerClass);
+
         String inputFilename = args[args.length-2];
         String outputFilename = args[args.length-1];
 
@@ -742,7 +835,7 @@
                 for (int i = 0; i < numKeys; ++i) {
                     int argNum = argstart + i*2;
                     publicKey[i] = readPublicKey(new File(args[argNum]));
-                    hashes |= getAlgorithm(publicKey[i]);
+                    hashes |= getDigestAlgorithm(publicKey[i]);
                 }
             } catch (IllegalArgumentException e) {
                 System.err.println(e);