Use static asan runtime for musl

Use static asan runtimes for musl binaries to match glibc binaries.
The static asan runtime also requires libclang_rt.asan_cxx.a.  Unlike
most other runtimes the asan runtimes need to expose the symbols
from the runtime to allow intercepting calls to malloc, new etc.

Test: m USE_HOST_MUSL=true aidl_unittests && out/host/linux-x86/testcases/aidl_unittests/x86_64/aidl_unittests
Test: sanitize_test.go
Change-Id: I93da03b1c447fbb01f37262e7a465f165c2d5a18
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index 052832d..6a10e14 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -212,6 +212,14 @@
 	return LibclangRuntimeLibrary(t, "asan")
 }
 
+func AddressSanitizerStaticRuntimeLibrary(t Toolchain) string {
+	return LibclangRuntimeLibrary(t, "asan.static")
+}
+
+func AddressSanitizerCXXStaticRuntimeLibrary(t Toolchain) string {
+	return LibclangRuntimeLibrary(t, "asan_cxx.static")
+}
+
 func HWAddressSanitizerRuntimeLibrary(t Toolchain) string {
 	return LibclangRuntimeLibrary(t, "hwasan")
 }
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 72c09fb..d8635e0 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -1539,7 +1539,13 @@
 		runtimeSharedLibrary := ""
 		toolchain := c.toolchain(mctx)
 		if Bool(sanProps.Address) {
-			runtimeSharedLibrary = config.AddressSanitizerRuntimeLibrary(toolchain)
+			if toolchain.Musl() || (c.staticBinary() && toolchain.Bionic()) {
+				// Use a static runtime for musl to match what clang does for glibc.
+				addStaticDeps(config.AddressSanitizerStaticRuntimeLibrary(toolchain), false)
+				addStaticDeps(config.AddressSanitizerCXXStaticRuntimeLibrary(toolchain), false)
+			} else {
+				runtimeSharedLibrary = config.AddressSanitizerRuntimeLibrary(toolchain)
+			}
 		} else if Bool(sanProps.Hwaddress) {
 			if c.staticBinary() {
 				addStaticDeps(config.HWAddressSanitizerStaticLibrary(toolchain), true)
diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go
index 71c5a22..718186d 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -127,6 +127,7 @@
 const (
 	RUNTIME_LINKAGE_NONE   = expectedRuntimeLinkage(0)
 	RUNTIME_LINKAGE_SHARED = iota
+	RUNTIME_LINKAGE_STATIC
 )
 
 func TestAsan(t *testing.T) {
@@ -245,6 +246,8 @@
 		libStaticAsanNoAsanVariant := result.ModuleForTests("libstatic_asan", staticVariant)
 
 		libAsanSharedRuntime := result.ModuleForTests("libclang_rt.asan", sharedVariant)
+		libAsanStaticRuntime := result.ModuleForTests("libclang_rt.asan.static", staticVariant)
+		libAsanStaticCxxRuntime := result.ModuleForTests("libclang_rt.asan_cxx.static", staticVariant)
 
 		expectSharedLinkDep(t, ctx, binWithAsan, libShared)
 		expectSharedLinkDep(t, ctx, binWithAsan, libAsan)
@@ -289,12 +292,38 @@
 			expectNoSharedLinkDep(t, ctx, libShared, libAsanSharedRuntime)
 			expectNoSharedLinkDep(t, ctx, libTransitive, libAsanSharedRuntime)
 		}
+
+		if runtimeLinkage == RUNTIME_LINKAGE_STATIC {
+			expectStaticLinkDep(t, ctx, binWithAsan, libAsanStaticRuntime)
+			expectNoStaticLinkDep(t, ctx, binNoAsan, libAsanStaticRuntime)
+			expectStaticLinkDep(t, ctx, libAsan, libAsanStaticRuntime)
+			expectNoStaticLinkDep(t, ctx, libShared, libAsanStaticRuntime)
+			expectNoStaticLinkDep(t, ctx, libTransitive, libAsanStaticRuntime)
+
+			expectStaticLinkDep(t, ctx, binWithAsan, libAsanStaticCxxRuntime)
+			expectNoStaticLinkDep(t, ctx, binNoAsan, libAsanStaticCxxRuntime)
+			expectStaticLinkDep(t, ctx, libAsan, libAsanStaticCxxRuntime)
+			expectNoStaticLinkDep(t, ctx, libShared, libAsanStaticCxxRuntime)
+			expectNoStaticLinkDep(t, ctx, libTransitive, libAsanStaticCxxRuntime)
+		} else {
+			expectNoStaticLinkDep(t, ctx, binWithAsan, libAsanStaticRuntime)
+			expectNoStaticLinkDep(t, ctx, binNoAsan, libAsanStaticRuntime)
+			expectNoStaticLinkDep(t, ctx, libAsan, libAsanStaticRuntime)
+			expectNoStaticLinkDep(t, ctx, libShared, libAsanStaticRuntime)
+			expectNoStaticLinkDep(t, ctx, libTransitive, libAsanStaticRuntime)
+
+			expectNoStaticLinkDep(t, ctx, binWithAsan, libAsanStaticCxxRuntime)
+			expectNoStaticLinkDep(t, ctx, binNoAsan, libAsanStaticCxxRuntime)
+			expectNoStaticLinkDep(t, ctx, libAsan, libAsanStaticCxxRuntime)
+			expectNoStaticLinkDep(t, ctx, libShared, libAsanStaticCxxRuntime)
+			expectNoStaticLinkDep(t, ctx, libTransitive, libAsanStaticCxxRuntime)
+		}
 	}
 
 	t.Run("host", func(t *testing.T) { check(t, buildOS, RUNTIME_LINKAGE_NONE, preparer) })
 	t.Run("device", func(t *testing.T) { check(t, "android_arm64_armv8-a", RUNTIME_LINKAGE_SHARED, preparer) })
 	t.Run("host musl", func(t *testing.T) {
-		check(t, "linux_musl_x86_64", RUNTIME_LINKAGE_SHARED,
+		check(t, "linux_musl_x86_64", RUNTIME_LINKAGE_STATIC,
 			android.GroupFixturePreparers(preparer, PrepareForTestWithHostMusl))
 	})
 }