Merge "Fix link_type checking"
diff --git a/core/binary.mk b/core/binary.mk
index b521dce..e11ab89 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -216,7 +216,6 @@
     ifneq (,$(filter r10 r11,$(LOCAL_NDK_VERSION)))
       ifeq (c++_static,$(LOCAL_NDK_STL_VARIANT))
         my_ndk_stl_static_lib := $(my_libcxx_libdir)/libc++_static.a
-        my_ldlibs += -ldl
       else
         my_ndk_stl_shared_lib_fullpath := $(my_libcxx_libdir)/libc++_shared.so
       endif
@@ -225,7 +224,6 @@
         my_ndk_stl_static_lib := \
           $(my_libcxx_libdir)/libc++_static.a \
           $(my_libcxx_libdir)/libc++abi.a
-        my_ldlibs += -ldl
       else
         my_ndk_stl_shared_lib_fullpath := $(my_libcxx_libdir)/libc++_shared.so
       endif
@@ -236,6 +234,8 @@
       endif
     endif
 
+    my_ldlibs += -ldl
+
     my_ndk_stl_cppflags := -std=c++11
   else # LOCAL_NDK_STL_VARIANT is not c++_* either
   ifneq (,$(filter gnustl_%, $(LOCAL_NDK_STL_VARIANT)))
@@ -418,7 +418,7 @@
 
 ifneq ($(LOCAL_NO_LIBCOMPILER_RT),true)
 # Add in libcompiler_rt for all regular device builds
-ifeq (,$(LOCAL_SDK_VERSION)$(WITHOUT_LIBCOMPILER_RT))
+ifeq (,$(WITHOUT_LIBCOMPILER_RT))
   my_static_libraries += $(COMPILER_RT_CONFIG_EXTRA_STATIC_LIBRARIES)
 endif
 endif
diff --git a/core/cleanbuild.mk b/core/cleanbuild.mk
index de6a5eb..6a29585 100644
--- a/core/cleanbuild.mk
+++ b/core/cleanbuild.mk
@@ -151,24 +151,18 @@
 # necessary to keep things consistent.
 
 previous_build_config_file := $(PRODUCT_OUT)/previous_build_config.mk
+current_build_config_file := $(PRODUCT_OUT)/current_build_config.mk
 
 current_build_config := \
     $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)
-current_sanitize_target := $(strip $(SANITIZE_TARGET))
-ifeq (,$(current_sanitize_target))
-  current_sanitize_target := false
-endif
 force_installclean := false
-force_objclean := false
 
 # Read the current state from the file, if present.
 # Will set PREVIOUS_BUILD_CONFIG.
 #
 PREVIOUS_BUILD_CONFIG :=
-PREVIOUS_SANITIZE_TARGET :=
 -include $(previous_build_config_file)
 PREVIOUS_BUILD_CONFIG := $(strip $(PREVIOUS_BUILD_CONFIG))
-PREVIOUS_SANITIZE_TARGET := $(strip $(PREVIOUS_SANITIZE_TARGET))
 
 ifdef PREVIOUS_BUILD_CONFIG
   ifneq "$(current_build_config)" "$(PREVIOUS_BUILD_CONFIG)"
@@ -181,27 +175,19 @@
   endif
 endif  # else, this is the first build, so no need to clean.
 
-ifdef PREVIOUS_SANITIZE_TARGET
-  ifneq "$(current_sanitize_target)" "$(PREVIOUS_SANITIZE_TARGET)"
-    $(info *** SANITIZE_TARGET changed: "$(PREVIOUS_SANITIZE_TARGET)" -> "$(current_sanitize_target)")
-    force_objclean := true
-  endif
-endif  # else, this is the first build, so no need to clean.
-
 # Write the new state to the file.
 #
-ifneq ($(PREVIOUS_BUILD_CONFIG)-$(PREVIOUS_SANITIZE_TARGET),$(current_build_config)-$(current_sanitize_target))
 $(shell \
-  mkdir -p $(dir $(previous_build_config_file)) && \
+  mkdir -p $(dir $(current_build_config_file)) && \
   echo "PREVIOUS_BUILD_CONFIG := $(current_build_config)" > \
-      $(previous_build_config_file) && \
-  echo "PREVIOUS_SANITIZE_TARGET := $(current_sanitize_target)" >> \
-      $(previous_build_config_file) \
+      $(current_build_config_file) \
  )
-endif
+$(shell cmp $(current_build_config_file) $(previous_build_config_file) > /dev/null 2>&1 || \
+  mv -f $(current_build_config_file) $(previous_build_config_file))
+
 PREVIOUS_BUILD_CONFIG :=
-PREVIOUS_SANITIZE_TARGET :=
 previous_build_config_file :=
+current_build_config_file :=
 current_build_config :=
 
 #
@@ -248,12 +234,6 @@
 	$(PRODUCT_OUT)/data-qemu/* \
 	$(PRODUCT_OUT)/userdata-qemu.img
 
-# The files/dirs to delete during an objclean, which removes any files
-# in the staging and emulator data partitions.
-objclean_files := \
-	$(TARGET_OUT_INTERMEDIATES) \
-	$($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES)
-
 # make sure *_OUT is set so that we won't result in deleting random parts
 # of the filesystem.
 ifneq (2,$(words $(HOST_OUT) $(PRODUCT_OUT)))
@@ -273,12 +253,6 @@
 	$(hide) rm -rf $(FILES)
 	@echo "Deleted images and staging directories."
 
-.PHONY: objclean
-objclean: FILES := $(objclean_files)
-objclean:
-	$(hide) rm -rf $(FILES)
-	@echo "Deleted images and staging directories."
-
 ifeq "$(force_installclean)" "true"
   $(info *** Forcing "make installclean"...)
   $(info *** rm -rf $(dataclean_files) $(installclean_files))
@@ -287,14 +261,6 @@
 endif
 force_installclean :=
 
-ifeq "$(force_objclean)" "true"
-  $(info *** Forcing cleanup of intermediate files...)
-  $(info *** rm -rf $(objclean_files))
-  $(shell rm -rf $(objclean_files))
-  $(info *** Done with the cleaning, now starting the real build.)
-endif
-force_objclean :=
-
 ###########################################################
 
 .PHONY: clean-jack-files
diff --git a/core/config.mk b/core/config.mk
index 3c2384c..525b639 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -40,21 +40,6 @@
 $(error Please remove --color=always from your  $$GREP_OPTIONS)
 endif
 
-# Standard source directories.
-# TODO: Enforce some kind of layering; only add include paths
-#       when a module links against a particular library.
-# TODO: See if we can remove most of these from the global list.
-SRC_SYSTEM_HEADERS := \
-	$(wildcard system/core/include) \
-	$(wildcard system/media/audio/include) \
-	$(wildcard hardware/libhardware/include) \
-	$(wildcard hardware/libhardware_legacy/include) \
-	$(wildcard hardware/ril/include) \
-	$(wildcard libnativehelper/include) \
-	$(wildcard frameworks/native/include) \
-	$(wildcard frameworks/native/opengl/include) \
-	$(wildcard frameworks/av/include) \
-	$(wildcard frameworks/base/include)
 SRC_TARGET_DIR := $(TOPDIR)build/target
 SRC_API_DIR := $(TOPDIR)prebuilts/sdk/api
 SRC_SYSTEM_API_DIR := $(TOPDIR)prebuilts/sdk/system-api
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 39a754b..8794c8a 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -469,7 +469,7 @@
 TARGET_ROOT_OUT_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)
 TARGET_ROOT_OUT_SBIN_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/sbin
 TARGET_ROOT_OUT_BIN_UNSTRIPPED := $(TARGET_OUT_UNSTRIPPED)/bin
-TARGET_OUT_COVERAGE := $(PRODUCT_OUT)/coverages
+TARGET_OUT_COVERAGE := $(PRODUCT_OUT)/coverage
 
 TARGET_ROOT_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ROOT)
 TARGET_ROOT_OUT_BIN := $(TARGET_ROOT_OUT)/bin
diff --git a/core/goma.mk b/core/goma.mk
index 52726be..4e8318a 100644
--- a/core/goma.mk
+++ b/core/goma.mk
@@ -49,7 +49,9 @@
   # gomacc can start goma client's daemon process automatically, but
   # it is safer and faster to start up it beforehand. We run this as a
   # background process so this won't slow down the build.
-  $(shell ( $(goma_ctl) ensure_start ) &> /dev/null &)
+  ifndef NOSTART_GOMA
+    $(shell ( $(goma_ctl) ensure_start ) &> /dev/null &)
+  endif
 
   goma_ctl :=
   goma_dir :=
diff --git a/tools/releasetools/check_ota_package_signature.py b/tools/releasetools/check_ota_package_signature.py
new file mode 100755
index 0000000..0da61b1
--- /dev/null
+++ b/tools/releasetools/check_ota_package_signature.py
@@ -0,0 +1,161 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 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.
+
+"""
+Verify a given OTA package with the specifed certificate.
+"""
+
+from __future__ import print_function
+
+import argparse
+import common
+import re
+import subprocess
+import sys
+
+from hashlib import sha1
+from hashlib import sha256
+
+
+def cert_uses_sha256(cert):
+  """Check if the cert uses SHA-256 hashing algorithm."""
+
+  cmd = ['openssl', 'x509', '-text', '-noout', '-in', cert]
+  p1 = common.Run(cmd, stdout=subprocess.PIPE)
+  cert_dump, _ = p1.communicate()
+
+  algorithm = re.search(r'Signature Algorithm: ([a-zA-Z0-9]+)', cert_dump)
+  assert algorithm, "Failed to identify the signature algorithm."
+
+  assert not algorithm.group(1).startswith('ecdsa'), (
+      'This script doesn\'t support verifying ECDSA signed package yet.')
+
+  return algorithm.group(1).startswith('sha256')
+
+
+def verify_package(cert, package):
+  """Verify the given package with the certificate.
+
+  (Comments from bootable/recovery/verifier.cpp:)
+
+  An archive with a whole-file signature will end in six bytes:
+
+    (2-byte signature start) $ff $ff (2-byte comment size)
+
+  (As far as the ZIP format is concerned, these are part of the
+  archive comment.) We start by reading this footer, this tells
+  us how far back from the end we have to start reading to find
+  the whole comment.
+  """
+
+  print('Package: %s' % (package,))
+  print('Certificate: %s' % (cert,))
+
+  # Read in the package.
+  with open(package) as package_file:
+    package_bytes = package_file.read()
+
+  length = len(package_bytes)
+  assert length >= 6, "Not big enough to contain footer."
+
+  footer = [ord(x) for x in package_bytes[-6:]]
+  assert footer[2] == 0xff and footer[3] == 0xff, "Footer is wrong."
+
+  signature_start_from_end = (footer[1] << 8) + footer[0]
+  assert signature_start_from_end > 6, "Signature start is in the footer."
+
+  signature_start = length - signature_start_from_end
+
+  # Determine how much of the file is covered by the signature. This is
+  # everything except the signature data and length, which includes all of the
+  # EOCD except for the comment length field (2 bytes) and the comment data.
+  comment_len = (footer[5] << 8) + footer[4]
+  signed_len = length - comment_len - 2
+
+  print('Package length: %d' % (length,))
+  print('Comment length: %d' % (comment_len,))
+  print('Signed data length: %d' % (signed_len,))
+  print('Signature start: %d' % (signature_start,))
+
+  use_sha256 = cert_uses_sha256(cert)
+  print('Use SHA-256: %s' % (use_sha256,))
+
+  if use_sha256:
+    h = sha256()
+  else:
+    h = sha1()
+  h.update(package_bytes[:signed_len])
+  package_digest = h.hexdigest().lower()
+
+  print('Digest: %s\n' % (package_digest,))
+
+  # Get the signature from the input package.
+  signature = package_bytes[signature_start:-6]
+  sig_file = common.MakeTempFile(prefix='sig-', suffix='')
+  with open(sig_file, 'wb') as f:
+    f.write(signature)
+
+  # Parse the signature and get the hash.
+  cmd = ['openssl', 'asn1parse', '-inform', 'DER', '-in', sig_file]
+  p1 = common.Run(cmd, stdout=subprocess.PIPE)
+  sig, _ = p1.communicate()
+  assert p1.returncode == 0, "Failed to parse the signature."
+
+  digest_line = sig.strip().split('\n')[-1]
+  digest_string = digest_line.split(':')[3]
+  digest_file = common.MakeTempFile(prefix='digest-', suffix='')
+  with open(digest_file, 'wb') as f:
+    f.write(digest_string.decode('hex'))
+
+  # Verify the digest by outputing the decrypted result in ASN.1 structure.
+  decrypted_file = common.MakeTempFile(prefix='decrypted-', suffix='')
+  cmd = ['openssl', 'rsautl', '-verify', '-certin', '-inkey', cert,
+         '-in', digest_file, '-out', decrypted_file]
+  p1 = common.Run(cmd, stdout=subprocess.PIPE)
+  p1.communicate()
+  assert p1.returncode == 0, "Failed to run openssl rsautl -verify."
+
+  # Parse the output ASN.1 structure.
+  cmd = ['openssl', 'asn1parse', '-inform', 'DER', '-in', decrypted_file]
+  p1 = common.Run(cmd, stdout=subprocess.PIPE)
+  decrypted_output, _ = p1.communicate()
+  assert p1.returncode == 0, "Failed to parse the output."
+
+  digest_line = decrypted_output.strip().split('\n')[-1]
+  digest_string = digest_line.split(':')[3].lower()
+
+  # Verify that the two digest strings match.
+  assert package_digest == digest_string, "Verification failed."
+
+  # Verified successfully upon reaching here.
+  print('VERIFIED\n')
+
+
+def main():
+  parser = argparse.ArgumentParser()
+  parser.add_argument('certificate', help='The certificate to be used.')
+  parser.add_argument('package', help='The OTA package to be verified.')
+  args = parser.parse_args()
+
+  verify_package(args.certificate, args.package)
+
+
+if __name__ == '__main__':
+  try:
+    main()
+  except AssertionError as err:
+    print('\n    ERROR: %s\n' % (err,))
+    sys.exit(1)