make: HWASan exclude path support

Like aosp/2495518, but adds the ability to centrally disable HWASan
for multiple modules when building with SANITIZE_TARGET=hwaddress.

HWASan takes precedence over CFI and several other sanitizers that it's
incompatible with[1], which can be problematic for modules that require
those sanitizers (e.g. those that depend on vendor prebuilts where only
sanitized variants are provided). This patch adds an easy way to disable
HWASan for such modules while still keeping it globally enabled.

Test: build with HWASAN_EXCLUDE_PATHS set and verify with readelf that
      relevant modules have no references to __hwasan symbols

[1] https://android.googlesource.com/platform/build/+/bb31ca1168df6326d6f8eee7a834a974aafed6ed/core/config_sanitizers.mk#236

Change-Id: I64185b570bc64e61680c3212934a02d80a4904b9
diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk
index 82b17be..049e7ff 100644
--- a/core/config_sanitizers.mk
+++ b/core/config_sanitizers.mk
@@ -65,6 +65,18 @@
   endif
 endif
 
+# Disable global HWASan in excluded paths
+ifneq ($(filter hwaddress, $(my_global_sanitize)),)
+  combined_exclude_paths := $(HWASAN_EXCLUDE_PATHS) \
+                            $(PRODUCT_HWASAN_EXCLUDE_PATHS)
+
+  ifneq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_exclude_paths)),\
+         $(filter $(dir)%,$(LOCAL_PATH)))),)
+    my_global_sanitize := $(filter-out hwaddress,$(my_global_sanitize))
+    my_global_sanitize_diag := $(filter-out hwaddress,$(my_global_sanitize_diag))
+  endif
+endif
+
 ifneq ($(my_global_sanitize),)
   my_sanitize := $(my_global_sanitize) $(my_sanitize)
 endif
diff --git a/core/product.mk b/core/product.mk
index b66f1e2..9912a52 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -254,6 +254,9 @@
 # Whether any paths should have HWASan enabled for components
 _product_list_vars += PRODUCT_HWASAN_INCLUDE_PATHS
 
+# Whether any paths are excluded from sanitization when SANITIZE_TARGET=hwaddress
+_product_list_vars += PRODUCT_HWASAN_EXCLUDE_PATHS
+
 # Whether any paths should have Memtag_heap enabled for components
 _product_list_vars += PRODUCT_MEMTAG_HEAP_ASYNC_INCLUDE_PATHS
 _product_list_vars += PRODUCT_MEMTAG_HEAP_ASYNC_DEFAULT_INCLUDE_PATHS
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 26998ed..ea9d3fb 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -115,6 +115,7 @@
 $(call add_json_list, CFIIncludePaths,                   $(CFI_INCLUDE_PATHS) $(PRODUCT_CFI_INCLUDE_PATHS))
 $(call add_json_list, IntegerOverflowExcludePaths,       $(INTEGER_OVERFLOW_EXCLUDE_PATHS) $(PRODUCT_INTEGER_OVERFLOW_EXCLUDE_PATHS))
 $(call add_json_list, HWASanIncludePaths,                $(HWASAN_INCLUDE_PATHS) $(PRODUCT_HWASAN_INCLUDE_PATHS))
+$(call add_json_list, HWASanExcludePaths,                $(HWASAN_EXCLUDE_PATHS) $(PRODUCT_HWASAN_EXCLUDE_PATHS))
 
 $(call add_json_list, MemtagHeapExcludePaths,            $(MEMTAG_HEAP_EXCLUDE_PATHS) $(PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS))
 $(call add_json_list, MemtagHeapAsyncIncludePaths,       $(MEMTAG_HEAP_ASYNC_INCLUDE_PATHS) $(PRODUCT_MEMTAG_HEAP_ASYNC_INCLUDE_PATHS) $(if $(filter true,$(PRODUCT_MEMTAG_HEAP_SKIP_DEFAULT_PATHS)),,$(PRODUCT_MEMTAG_HEAP_ASYNC_DEFAULT_INCLUDE_PATHS)))