Teach soong not to duplicate the HWASAN runtime into each APEX.

When HWASAN is enabled, the runtime is conceptually part of Bionic (and
mutually depends on it), so it needs to be treated in the same way as the
Bionic libs.

Now there are only two copies of the runtime: the one in
/system/lib64/bootstrap (which won't be used by ordinary processes) and the
one in the runtime APEX.

This reduces the size of the HWASAN system image and fixes an issue where
multiple copies of the HWASAN runtime were being loaded into 64-bit binaries in
APEXes because the linker namespace for the binary is different from the one
for its dependent libraries outside of APEXes. HWASAN only supports loading
one copy of the runtime per process, so this was causing such binaries to
crash on startup.

Change-Id: I228896e193a035e6dfba9f6e28d0b2e12fc163ea
diff --git a/apex/apex.go b/apex/apex.go
index 68d0bc1..51d0718 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -521,6 +521,17 @@
 					a.properties.Multilib.Prefer32.Binaries, target.String(),
 					a.getImageVariation(config))
 			}
+
+			if strings.HasPrefix(ctx.ModuleName(), "com.android.runtime") && target.Os.Class == android.Device {
+				for _, sanitizer := range ctx.Config().SanitizeDevice() {
+					if sanitizer == "hwaddress" {
+						addDependenciesForNativeModules(ctx,
+							[]string{"libclang_rt.hwasan-aarch64-android"},
+							nil, target.String(), a.getImageVariation(config))
+						break
+					}
+				}
+			}
 		}
 
 	}
diff --git a/cc/binary.go b/cc/binary.go
index 51e68fc..93d1de2 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -440,8 +440,8 @@
 	// Bionic binaries (e.g. linker) is installed to the bootstrap subdirectory.
 	// The original path becomes a symlink to the corresponding file in the
 	// runtime APEX.
-	if isBionic(ctx.baseModuleName()) && ctx.Arch().Native && ctx.apexName() == "" && !ctx.inRecovery() {
-		if ctx.Device() {
+	if installToBootstrap(ctx.baseModuleName(), ctx.Config()) && ctx.Arch().Native && ctx.apexName() == "" && !ctx.inRecovery() {
+		if ctx.Device() && isBionic(ctx.baseModuleName()) {
 			binary.installSymlinkToRuntimeApex(ctx, file)
 		}
 		binary.baseInstaller.subDir = "bootstrap"
diff --git a/cc/cc.go b/cc/cc.go
index a3b9a92..786e4fd 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -600,6 +600,9 @@
 	if library, ok := c.linker.(*libraryDecorator); ok {
 		return len(library.Properties.Stubs.Versions) > 0
 	}
+	if library, ok := c.linker.(*prebuiltLibraryLinker); ok {
+		return len(library.Properties.Stubs.Versions) > 0
+	}
 	return false
 }
 
@@ -619,6 +622,13 @@
 	return false
 }
 
+func installToBootstrap(name string, config android.Config) bool {
+	if name == "libclang_rt.hwasan-aarch64-android" {
+		return inList("hwaddress", config.SanitizeDevice())
+	}
+	return isBionic(name)
+}
+
 type baseModuleContext struct {
 	android.BaseContext
 	moduleContextImpl
diff --git a/cc/library.go b/cc/library.go
index c2ab098..97b3cec 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -958,12 +958,12 @@
 					library.baseInstaller.subDir += "-" + vndkVersion
 				}
 			}
-		} else if len(library.Properties.Stubs.Versions) > 0 && android.DirectlyInAnyApex(ctx, ctx.ModuleName()) {
+		} else if len(library.Properties.Stubs.Versions) > 0 {
 			// Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory.
 			// The original path becomes a symlink to the corresponding file in the
 			// runtime APEX.
-			if isBionic(ctx.baseModuleName()) && !library.buildStubs() && ctx.Arch().Native && !ctx.inRecovery() {
-				if ctx.Device() {
+			if installToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() && ctx.Arch().Native && !ctx.inRecovery() {
+				if ctx.Device() && isBionic(ctx.baseModuleName()) {
 					library.installSymlinkToRuntimeApex(ctx, file)
 				}
 				library.baseInstaller.subDir = "bootstrap"
diff --git a/cc/makevars.go b/cc/makevars.go
index 3c24f34..a71f479 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -96,7 +96,20 @@
 
 	ctx.Strict("VNDK_CORE_LIBRARIES", strings.Join(*vndkCoreLibraries(ctx.Config()), " "))
 	ctx.Strict("VNDK_SAMEPROCESS_LIBRARIES", strings.Join(*vndkSpLibraries(ctx.Config()), " "))
-	ctx.Strict("LLNDK_LIBRARIES", strings.Join(*llndkLibraries(ctx.Config()), " "))
+
+	// Make uses LLNDK_LIBRARIES to determine which libraries to install.
+	// HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN.
+	// Therefore, by removing the library here, we cause it to only be installed if libc
+	// depends on it.
+	installedLlndkLibraries := []string{}
+	for _, lib := range *llndkLibraries(ctx.Config()) {
+		if strings.HasPrefix(lib, "libclang_rt.hwasan-") {
+			continue
+		}
+		installedLlndkLibraries = append(installedLlndkLibraries, lib)
+	}
+	ctx.Strict("LLNDK_LIBRARIES", strings.Join(installedLlndkLibraries, " "))
+
 	ctx.Strict("VNDK_PRIVATE_LIBRARIES", strings.Join(*vndkPrivateLibraries(ctx.Config()), " "))
 	ctx.Strict("VNDK_USING_CORE_VARIANT_LIBRARIES", strings.Join(*vndkUsingCoreVariantLibraries(ctx.Config()), " "))