Add "hwaddress" sanitizer.

Build/make support for "hwaddress".

* HWASan supports static binaries, unlike ASan.
* It will be used to build libc. Since static libraries get a .hwasan
  suffix in soong, the logic that moves libc-and-friends to the end
  of the link command line has to be updated.

Bug: 112438058
Test: manual, part of a bigger patch set

Change-Id: I3b52336841012622771a88ba161916bc33071dfe
diff --git a/core/Makefile b/core/Makefile
index 40f252f..afebd35 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1664,7 +1664,7 @@
 
 # ASAN libraries in the system image - add dependency.
 ASAN_IN_SYSTEM_INSTALLED := $(TARGET_OUT)/asan.tar.bz2
-ifneq (,$(SANITIZE_TARGET))
+ifneq (,$(filter address, $(SANITIZE_TARGET)))
   ifeq (true,$(SANITIZE_TARGET_SYSTEM))
     FULL_SYSTEMIMAGE_DEPS += $(ASAN_IN_SYSTEM_INSTALLED)
   endif
diff --git a/core/binary.mk b/core/binary.mk
index 73d420c..74e08d3 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1320,6 +1320,24 @@
     $(my_static_libraries))
 endif
 
+ifneq ($(LOCAL_USE_VNDK),)
+  my_soong_hwasan_static_libraries := $(SOONG_HWASAN_VENDOR_STATIC_LIBRARIES)
+else
+  my_soong_hwasan_static_libraries = $(SOONG_HWASAN_STATIC_LIBRARIES)
+endif
+
+define use_soong_hwasan_static_libraries
+  $(foreach l,$(1),$(if $(filter $(l),$(my_soong_hwasan_static_libraries)),\
+      $(l).hwasan,$(l)))
+endef
+
+ifneq ($(filter hwaddress,$(my_sanitize)),)
+  my_whole_static_libraries := $(call use_soong_hwasan_static_libraries,\
+    $(my_whole_static_libraries))
+  my_static_libraries := $(call use_soong_hwasan_static_libraries,\
+    $(my_static_libraries))
+endif
+
 ###########################################################
 ## When compiling against the VNDK, use LL-NDK libraries
 ###########################################################
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index 083da9f..333e825 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -174,6 +174,24 @@
   my_sanitize := $(filter-out $(my_nosanitize),$(my_sanitize))
 endif
 
+ifneq ($(filter arm x86 x86_64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
+  my_sanitize := $(filter-out hwaddress,$(my_sanitize))
+endif
+
+ifneq ($(filter hwaddress,$(my_sanitize)),)
+  my_sanitize := $(filter-out address,$(my_sanitize))
+  my_sanitize := $(filter-out thread,$(my_sanitize))
+endif
+
+ifneq ($(filter hwaddress,$(my_sanitize)),)
+  my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)HWADDRESS_SANITIZER_RUNTIME_LIBRARY)
+  ifeq ($(LOCAL_MODULE_CLASS),EXECUTABLES)
+    ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
+      my_static_libraries := $(my_static_libraries) $($(LOCAL_2ND_ARCH_VAR_PREFIX)HWADDRESS_SANITIZER_STATIC_LIBRARY)
+    endif
+  endif
+endif
+
 # TSAN is not supported on 32-bit architectures. For non-multilib cases, make
 # its use an error. For multilib cases, don't use it for the 32-bit case.
 ifneq ($(filter thread,$(my_sanitize)),)
@@ -195,7 +213,7 @@
 endif
 
 # Disable Scudo if ASan or TSan is enabled.
-ifneq ($(filter address thread,$(my_sanitize)),)
+ifneq ($(filter address thread hwaddress,$(my_sanitize)),)
   my_sanitize := $(filter-out scudo,$(my_sanitize))
 endif
 
@@ -364,7 +382,7 @@
   ifneq ($(filter unsigned-integer-overflow signed-integer-overflow integer,$(my_sanitize)),)
     ifeq ($(filter unsigned-integer-overflow signed-integer overflow integer,$(my_sanitize_diag)),)
       ifeq ($(filter cfi,$(my_sanitize_diag)),)
-        ifeq ($(filter address,$(my_sanitize)),)
+        ifeq ($(filter address hwaddress,$(my_sanitize)),)
           my_cflags += -fsanitize-minimal-runtime
           my_cflags += -fno-sanitize-trap=integer
           my_cflags += -fno-sanitize-recover=integer
@@ -387,7 +405,7 @@
     notrap_arg := $(subst $(space),$(comma),$(my_sanitize_diag)),
     my_cflags += -fno-sanitize-trap=$(notrap_arg)
     # Diagnostic requires a runtime library, unless ASan or TSan are also enabled.
-    ifeq ($(filter address thread scudo,$(my_sanitize)),)
+    ifeq ($(filter address thread scudo hwaddress,$(my_sanitize)),)
       # Does not have to be the first DT_NEEDED unlike ASan.
       my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_RUNTIME_LIBRARY)
     endif
diff --git a/core/definitions.mk b/core/definitions.mk
index 291441b..02eb725 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -1949,13 +1949,13 @@
 	-Wl,--whole-archive \
 	$(PRIVATE_ALL_WHOLE_STATIC_LIBRARIES) \
 	-Wl,--no-whole-archive \
-	$(filter-out %libcompiler_rt.a,$(filter-out %libc_nomalloc.a,$(filter-out %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)))) \
+	$(filter-out %libcompiler_rt.hwasan.a %libc_nomalloc.hwasan.a %libc.hwasan.a %libcompiler_rt.a %libc_nomalloc.a %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	-Wl,--start-group \
-	$(filter %libc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
-	$(filter %libc_nomalloc.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+	$(filter %libc.a %libc.hwasan.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+	$(filter %libc_nomalloc.a %libc_nomalloc.hwasan.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(if $(filter true,$(NATIVE_COVERAGE)),$(PRIVATE_TARGET_COVERAGE_LIB)) \
 	$(PRIVATE_TARGET_LIBATOMIC) \
-	$(filter %libcompiler_rt.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
+	$(filter %libcompiler_rt.a %libcompiler_rt.hwasan.a,$(PRIVATE_ALL_STATIC_LIBRARIES)) \
 	$(PRIVATE_TARGET_LIBGCC) \
 	-Wl,--end-group \
 	$(PRIVATE_TARGET_CRTEND_O)