Introduce hwasan mode for linker

This mode instructs the linker to search for libraries in hwasan
subdirectories of all library search paths. This is set up to contain a
hwasan-enabled copy of libc, which is needed for HWASan programs to
operate. There are two ways this mode can be enabled:

* for native binaries, by using the linker_hwasan64 symlink as its
  interpreter
* for apps: by setting the LD_HWASAN environment variable in wrap.sh

Bug: 276930343
Change-Id: I0f4117a50091616f26947fbe37a28ee573b97ad0
diff --git a/libc/Android.bp b/libc/Android.bp
index 93f9ce9..1a7a1af 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1674,13 +1674,12 @@
 // ========================================================
 // libc.a + libc.so
 // ========================================================
-cc_library {
+cc_defaults {
     defaults: [
         "libc_defaults",
         "libc_native_allocator_defaults",
     ],
-    name: "libc",
-    static_ndk_lib: true,
+    name: "libc_library_defaults",
     product_variables: {
         platform_sdk_version: {
             asflags: ["-DPLATFORM_SDK_VERSION=%d"],
@@ -1807,20 +1806,7 @@
         },
     },
 
-    stubs: {
-        symbol_file: "libc.map.txt",
-        versions: [
-            "29",
-            "R",
-            "current",
-        ],
-    },
-    llndk: {
-        symbol_file: "libc.map.txt",
-        export_headers_as_system: true,
-        export_preprocessed_headers: ["include"],
-        export_llndk_headers: ["libc_llndk_headers"],
-    },
+
     apex_available: [
         "//apex_available:platform",
         "com.android.runtime",
@@ -1835,6 +1821,55 @@
     },
 }
 
+cc_library {
+    name: "libc",
+      defaults: [
+        "libc_library_defaults",
+    ],
+    stubs: {
+        symbol_file: "libc.map.txt",
+        versions: [
+            "29",
+            "R",
+            "current",
+        ],
+    },
+    static_ndk_lib: true,
+    llndk: {
+        symbol_file: "libc.map.txt",
+        export_headers_as_system: true,
+        export_preprocessed_headers: ["include"],
+        export_llndk_headers: ["libc_llndk_headers"],
+    },
+}
+
+cc_library {
+    name: "libc_hwasan",
+      defaults: [
+        "libc_library_defaults",
+    ],
+    sanitize: {
+        hwaddress: true,
+    },
+    enabled: false,
+    arch: {
+        arm64: {
+            enabled: true,
+        },
+    },
+    stem: "libc",
+    relative_install_path: "hwasan",
+    // We don't really need the stubs, but this needs to stay to trigger the
+    // symlink logic in soong.
+    stubs: {
+        symbol_file: "libc.map.txt",
+    },
+    native_bridge_supported: false,
+    // It is never correct to depend on this directly. This is only
+    // needed for the runtime apex, and in base_system.mk.
+    visibility: ["//bionic/apex"],
+}
+
 genrule {
     name: "libc.arm.map",
     out: ["libc.arm.map"],
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 5d5ecac..59b2ddb 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -289,6 +289,7 @@
       "LD_DEBUG",
       "LD_DEBUG_OUTPUT",
       "LD_DYNAMIC_WEAK",
+      "LD_HWASAN",
       "LD_LIBRARY_PATH",
       "LD_ORIGIN_PATH",
       "LD_PRELOAD",