Allow Linux hosts to use ubsan runtime sanitizers.

Linux host prebuilts for UBSan runtime are available now, so we can enable
these. There's a bit more work to be done for Windows/Darwin support, so
that's left to another CL.

Bug: 148289941
Test: Build host binary with integer overflow sanitization enabled.
Change-Id: I9b06a63da6f0d6644273085ad6ffd42677fa2baa
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index f08a379..13b5511 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -234,7 +234,7 @@
 }
 
 func (toolchainLinuxX86) LibclangRuntimeLibraryArch() string {
-	return "i686"
+	return "i386"
 }
 
 func (toolchainLinuxX8664) LibclangRuntimeLibraryArch() string {
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 93c4b41..ecaafe4 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -334,8 +334,8 @@
 		s.Diag.Cfi = nil
 	}
 
-	// Disable sanitizers that depend on the UBSan runtime for host builds.
-	if ctx.Host() {
+	// Disable sanitizers that depend on the UBSan runtime for windows/darwin builds.
+	if !ctx.Os().Linux() {
 		s.Cfi = nil
 		s.Diag.Cfi = nil
 		s.Misc_undefined = nil
@@ -433,11 +433,18 @@
 func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
 	minimalRuntimeLib := config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(ctx.toolchain()) + ".a"
 	minimalRuntimePath := "${config.ClangAsanLibDir}/" + minimalRuntimeLib
+	builtinsRuntimeLib := config.BuiltinsRuntimeLibrary(ctx.toolchain()) + ".a"
+	builtinsRuntimePath := "${config.ClangAsanLibDir}/" + builtinsRuntimeLib
 
-	if ctx.Device() && sanitize.Properties.MinimalRuntimeDep {
+	if sanitize.Properties.MinimalRuntimeDep {
 		flags.Local.LdFlags = append(flags.Local.LdFlags,
 			minimalRuntimePath,
 			"-Wl,--exclude-libs,"+minimalRuntimeLib)
+		if ctx.Host() {
+			flags.Local.LdFlags = append(flags.Local.LdFlags,
+				builtinsRuntimePath,
+				"-Wl,--exclude-libs,"+builtinsRuntimeLib)
+		}
 	}
 	if !sanitize.Properties.SanitizerEnabled && !sanitize.Properties.UbsanRuntimeDep {
 		return flags
@@ -541,11 +548,15 @@
 			// there will always be undefined symbols in intermediate libraries.
 			_, flags.Global.LdFlags = removeFromList("-Wl,--no-undefined", flags.Global.LdFlags)
 			flags.Local.LdFlags = append(flags.Local.LdFlags, sanitizeArg)
-		} else {
-			if enableMinimalRuntime(sanitize) {
-				flags.Local.CFlags = append(flags.Local.CFlags, strings.Join(minimalRuntimeFlags, " "))
-				flags.libFlags = append([]string{minimalRuntimePath}, flags.libFlags...)
-				flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,"+minimalRuntimeLib)
+		}
+
+		if enableMinimalRuntime(sanitize) {
+			flags.Local.CFlags = append(flags.Local.CFlags, strings.Join(minimalRuntimeFlags, " "))
+			flags.libFlags = append([]string{minimalRuntimePath}, flags.libFlags...)
+			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,"+minimalRuntimeLib)
+			if !ctx.toolchain().Bionic() {
+				flags.libFlags = append([]string{builtinsRuntimePath}, flags.libFlags...)
+				flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,"+builtinsRuntimeLib)
 			}
 		}
 
@@ -888,34 +899,46 @@
 			runtimeLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain)
 		}
 
-		if mctx.Device() && runtimeLibrary != "" {
-			if isLlndkLibrary(runtimeLibrary, mctx.Config()) && !c.static() && c.UseVndk() {
-				runtimeLibrary = runtimeLibrary + llndkLibrarySuffix
-			}
+		if runtimeLibrary != "" {
+			// Devices and LinuxBionic use the same libraries.
+			if toolchain.Bionic() {
+				if isLlndkLibrary(runtimeLibrary, mctx.Config()) && !c.static() && c.UseVndk() {
+					runtimeLibrary = runtimeLibrary + llndkLibrarySuffix
+				}
 
-			// Adding dependency to the runtime library. We are using *FarVariation*
-			// because the runtime libraries themselves are not mutated by sanitizer
-			// mutators and thus don't have sanitizer variants whereas this module
-			// has been already mutated.
-			//
-			// Note that by adding dependency with {static|shared}DepTag, the lib is
-			// added to libFlags and LOCAL_SHARED_LIBRARIES by cc.Module
-			if c.staticBinary() {
-				// static executable gets static runtime libs
-				mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
-					{Mutator: "link", Variation: "static"},
-					c.ImageVariation(),
-				}...), StaticDepTag, append([]string{runtimeLibrary}, extraStaticDeps...)...)
-			} else if !c.static() && !c.header() {
-				// dynamic executable and shared libs get shared runtime libs
-				mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
-					{Mutator: "link", Variation: "shared"},
-					c.ImageVariation(),
-				}...), earlySharedDepTag, runtimeLibrary)
+				// Adding dependency to the runtime library. We are using *FarVariation*
+				// because the runtime libraries themselves are not mutated by sanitizer
+				// mutators and thus don't have sanitizer variants whereas this module
+				// has been already mutated.
+				//
+				// Note that by adding dependency with {static|shared}DepTag, the lib is
+				// added to libFlags and LOCAL_SHARED_LIBRARIES by cc.Module
+				if c.staticBinary() {
+					// static executable gets static runtime libs
+					mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
+						{Mutator: "link", Variation: "static"},
+						c.ImageVariation(),
+					}...), StaticDepTag, append([]string{runtimeLibrary}, extraStaticDeps...)...)
+				} else if !c.static() && !c.header() {
+					// dynamic executable and shared libs get shared runtime libs
+					mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
+						{Mutator: "link", Variation: "shared"},
+						c.ImageVariation(),
+					}...), earlySharedDepTag, runtimeLibrary)
+				}
+				// static lib does not have dependency to the runtime library. The
+				// dependency will be added to the executables or shared libs using
+				// the static lib.
+			} else {
+				if c.sanitize.Properties.UbsanRuntimeDep {
+					// Support UBSan runtime on host modules, which requires the builtins linked in as well.
+					mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
+						{Mutator: "link", Variation: "static"},
+						c.ImageVariation(),
+					}...), StaticDepTag, append([]string{runtimeLibrary, config.BuiltinsRuntimeLibrary(toolchain)},
+						extraStaticDeps...)...)
+				}
 			}
-			// static lib does not have dependency to the runtime library. The
-			// dependency will be added to the executables or shared libs using
-			// the static lib.
 		}
 	}
 }