Merge "APEXes can be sanitized" am: a09e13a4ab am: 81551d4616
am: d4e0239cd0

Change-Id: I97b508b66b40a00ad3684609c479c1c054b98339
diff --git a/apex/apex.go b/apex/apex.go
index e711c8b..6269868 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -482,6 +482,11 @@
 	}
 }
 
+func (a *apexBundle) IsSanitizerEnabled() bool {
+	// APEX can be mutated for sanitizers
+	return true
+}
+
 func getCopyManifestForNativeLibrary(cc *cc.Module) (fileToCopy android.Path, dirInApex string) {
 	// Decide the APEX-local directory by the multilib of the library
 	// In the future, we may query this to the module.
@@ -903,6 +908,9 @@
 				fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
 
 				for _, fi := range a.filesInfo {
+					if cc, ok := fi.module.(*cc.Module); ok && cc.Properties.HideFromMake {
+						continue
+					}
 					fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
 					fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
 					fmt.Fprintln(w, "LOCAL_MODULE :=", fi.moduleName)
diff --git a/cc/cc.go b/cc/cc.go
index 85e3a67..4717b72 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -60,6 +60,7 @@
 		ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
 
 		ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator)
+		ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
 
 		ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
 		ctx.TopDown("vndk_deps", sabiDepsMutator)
@@ -524,6 +525,8 @@
 func (c *Module) IsStubs() bool {
 	if library, ok := c.linker.(*libraryDecorator); ok {
 		return library.buildStubs()
+	} else if _, ok := c.linker.(*llndkStubDecorator); ok {
+		return true
 	}
 	return false
 }
@@ -569,12 +572,7 @@
 }
 
 func (ctx *moduleContextImpl) staticBinary() bool {
-	if static, ok := ctx.mod.linker.(interface {
-		staticBinary() bool
-	}); ok {
-		return static.staticBinary()
-	}
-	return false
+	return ctx.mod.staticBinary()
 }
 
 func (ctx *moduleContextImpl) useSdk() bool {
@@ -891,7 +889,7 @@
 	}
 }
 
-func (c *Module) toolchain(ctx BaseModuleContext) config.Toolchain {
+func (c *Module) toolchain(ctx android.BaseContext) config.Toolchain {
 	if c.cachedToolchain == nil {
 		c.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch())
 	}
@@ -1708,6 +1706,15 @@
 	return false
 }
 
+func (c *Module) staticBinary() bool {
+	if static, ok := c.linker.(interface {
+		staticBinary() bool
+	}); ok {
+		return static.staticBinary()
+	}
+	return false
+}
+
 func (c *Module) getMakeLinkType() string {
 	if c.useVndk() {
 		if inList(c.Name(), vndkCoreLibraries) || inList(c.Name(), vndkSpLibraries) || inList(c.Name(), llndkLibraries) {
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 47994a8..ffeeb69 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -103,6 +103,10 @@
 	return nil
 }
 
+func (p *prebuiltLibraryLinker) shared() bool {
+	return p.libraryDecorator.shared()
+}
+
 func prebuiltSharedLibraryFactory() android.Module {
 	module, _ := NewPrebuiltSharedLibrary(android.HostAndDeviceSupported)
 	return module.Init()
@@ -121,6 +125,10 @@
 	module.AddProperties(&prebuilt.properties)
 
 	android.InitPrebuiltModule(module, &prebuilt.properties.Srcs)
+
+	// Prebuilt libraries can be included in APEXes
+	android.InitApexModule(module)
+
 	return module, library
 }
 
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 8d33de5..d19e54a 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -16,7 +16,6 @@
 
 import (
 	"fmt"
-	"io"
 	"sort"
 	"strings"
 	"sync"
@@ -138,18 +137,17 @@
 		Blacklist *string
 	} `android:"arch_variant"`
 
-	SanitizerEnabled  bool `blueprint:"mutated"`
-	SanitizeDep       bool `blueprint:"mutated"`
-	MinimalRuntimeDep bool `blueprint:"mutated"`
-	UbsanRuntimeDep   bool `blueprint:"mutated"`
-	InSanitizerDir    bool `blueprint:"mutated"`
+	SanitizerEnabled  bool     `blueprint:"mutated"`
+	SanitizeDep       bool     `blueprint:"mutated"`
+	MinimalRuntimeDep bool     `blueprint:"mutated"`
+	UbsanRuntimeDep   bool     `blueprint:"mutated"`
+	InSanitizerDir    bool     `blueprint:"mutated"`
+	Sanitizers        []string `blueprint:"mutated"`
+	DiagSanitizers    []string `blueprint:"mutated"`
 }
 
 type sanitize struct {
 	Properties SanitizeProperties
-
-	runtimeLibrary          string
-	androidMkRuntimeLibrary string
 }
 
 func init() {
@@ -405,46 +403,6 @@
 		return flags
 	}
 
-	var sanitizers []string
-	var diagSanitizers []string
-
-	if Bool(sanitize.Properties.Sanitize.All_undefined) {
-		sanitizers = append(sanitizers, "undefined")
-	} else {
-		if Bool(sanitize.Properties.Sanitize.Undefined) {
-			sanitizers = append(sanitizers,
-				"bool",
-				"integer-divide-by-zero",
-				"return",
-				"returns-nonnull-attribute",
-				"shift-exponent",
-				"unreachable",
-				"vla-bound",
-				// TODO(danalbert): The following checks currently have compiler performance issues.
-				//"alignment",
-				//"bounds",
-				//"enum",
-				//"float-cast-overflow",
-				//"float-divide-by-zero",
-				//"nonnull-attribute",
-				//"null",
-				//"shift-base",
-				//"signed-integer-overflow",
-				// TODO(danalbert): Fix UB in libc++'s __tree so we can turn this on.
-				// https://llvm.org/PR19302
-				// http://reviews.llvm.org/D6974
-				// "object-size",
-			)
-		}
-		sanitizers = append(sanitizers, sanitize.Properties.Sanitize.Misc_undefined...)
-	}
-
-	if Bool(sanitize.Properties.Sanitize.Diag.Undefined) {
-		diagSanitizers = append(diagSanitizers, "undefined")
-	}
-
-	diagSanitizers = append(diagSanitizers, sanitize.Properties.Sanitize.Diag.Misc_undefined...)
-
 	if Bool(sanitize.Properties.Sanitize.Address) {
 		if ctx.Arch().ArchType == android.Arm {
 			// Frame pointer based unwinder in ASan requires ARM frame setup.
@@ -465,34 +423,22 @@
 				flags.DynamicLinker += "64"
 			}
 		}
-		sanitizers = append(sanitizers, "address")
-		diagSanitizers = append(diagSanitizers, "address")
 	}
 
 	if Bool(sanitize.Properties.Sanitize.Hwaddress) {
 		flags.CFlags = append(flags.CFlags, hwasanCflags...)
-		sanitizers = append(sanitizers, "hwaddress")
-	}
-
-	if Bool(sanitize.Properties.Sanitize.Thread) {
-		sanitizers = append(sanitizers, "thread")
 	}
 
 	if Bool(sanitize.Properties.Sanitize.Coverage) {
 		flags.CFlags = append(flags.CFlags, "-fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp")
 	}
 
-	if Bool(sanitize.Properties.Sanitize.Safestack) {
-		sanitizers = append(sanitizers, "safe-stack")
-	}
-
 	if Bool(sanitize.Properties.Sanitize.Cfi) {
 		if ctx.Arch().ArchType == android.Arm {
 			// __cfi_check needs to be built as Thumb (see the code in linker_cfi.cpp). LLVM is not set up
 			// to do this on a function basis, so force Thumb on the entire module.
 			flags.RequiredInstructionSet = "thumb"
 		}
-		sanitizers = append(sanitizers, "cfi")
 
 		flags.CFlags = append(flags.CFlags, cfiCflags...)
 		flags.AsFlags = append(flags.AsFlags, cfiAsflags...)
@@ -502,9 +448,6 @@
 			flags.CFlags = append(flags.CFlags, "-fvisibility=default")
 		}
 		flags.LdFlags = append(flags.LdFlags, cfiLdflags...)
-		if Bool(sanitize.Properties.Sanitize.Diag.Cfi) {
-			diagSanitizers = append(diagSanitizers, "cfi")
-		}
 
 		if ctx.staticBinary() {
 			_, flags.CFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.CFlags)
@@ -513,25 +456,11 @@
 	}
 
 	if Bool(sanitize.Properties.Sanitize.Integer_overflow) {
-		sanitizers = append(sanitizers, "unsigned-integer-overflow")
-		sanitizers = append(sanitizers, "signed-integer-overflow")
 		flags.CFlags = append(flags.CFlags, intOverflowCflags...)
-		if Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) {
-			diagSanitizers = append(diagSanitizers, "unsigned-integer-overflow")
-			diagSanitizers = append(diagSanitizers, "signed-integer-overflow")
-		}
 	}
 
-	if Bool(sanitize.Properties.Sanitize.Scudo) {
-		sanitizers = append(sanitizers, "scudo")
-	}
-
-	if Bool(sanitize.Properties.Sanitize.Scs) {
-		sanitizers = append(sanitizers, "shadow-call-stack")
-	}
-
-	if len(sanitizers) > 0 {
-		sanitizeArg := "-fsanitize=" + strings.Join(sanitizers, ",")
+	if len(sanitize.Properties.Sanitizers) > 0 {
+		sanitizeArg := "-fsanitize=" + strings.Join(sanitize.Properties.Sanitizers, ",")
 
 		flags.CFlags = append(flags.CFlags, sanitizeArg)
 		flags.AsFlags = append(flags.AsFlags, sanitizeArg)
@@ -556,8 +485,8 @@
 		}
 	}
 
-	if len(diagSanitizers) > 0 {
-		flags.CFlags = append(flags.CFlags, "-fno-sanitize-trap="+strings.Join(diagSanitizers, ","))
+	if len(sanitize.Properties.DiagSanitizers) > 0 {
+		flags.CFlags = append(flags.CFlags, "-fno-sanitize-trap="+strings.Join(sanitize.Properties.DiagSanitizers, ","))
 	}
 	// FIXME: enable RTTI if diag + (cfi or vptr)
 
@@ -571,46 +500,6 @@
 			strings.Join(sanitize.Properties.Sanitize.Diag.No_recover, ","))
 	}
 
-	// Link a runtime library if needed.
-	runtimeLibrary := ""
-	if Bool(sanitize.Properties.Sanitize.Address) {
-		runtimeLibrary = config.AddressSanitizerRuntimeLibrary(ctx.toolchain())
-	} else if Bool(sanitize.Properties.Sanitize.Hwaddress) {
-		runtimeLibrary = config.HWAddressSanitizerRuntimeLibrary(ctx.toolchain())
-	} else if Bool(sanitize.Properties.Sanitize.Thread) {
-		runtimeLibrary = config.ThreadSanitizerRuntimeLibrary(ctx.toolchain())
-	} else if Bool(sanitize.Properties.Sanitize.Scudo) {
-		if len(diagSanitizers) == 0 && !sanitize.Properties.UbsanRuntimeDep {
-			runtimeLibrary = config.ScudoMinimalRuntimeLibrary(ctx.toolchain())
-		} else {
-			runtimeLibrary = config.ScudoRuntimeLibrary(ctx.toolchain())
-		}
-	} else if len(diagSanitizers) > 0 || sanitize.Properties.UbsanRuntimeDep {
-		runtimeLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(ctx.toolchain())
-	}
-
-	if runtimeLibrary != "" {
-		runtimeLibraryPath := "${config.ClangAsanLibDir}/" + runtimeLibrary
-		if !ctx.static() {
-			runtimeLibraryPath = runtimeLibraryPath + ctx.toolchain().ShlibSuffix()
-		} else {
-			runtimeLibraryPath = runtimeLibraryPath + ".a"
-		}
-
-		// ASan runtime library must be the first in the link order.
-		flags.libFlags = append([]string{runtimeLibraryPath}, flags.libFlags...)
-		sanitize.runtimeLibrary = runtimeLibrary
-
-		// When linking against VNDK, use the vendor variant of the runtime lib
-		if ctx.useVndk() {
-			sanitize.androidMkRuntimeLibrary = sanitize.runtimeLibrary + vendorSuffix
-		} else if ctx.inRecovery() {
-			sanitize.androidMkRuntimeLibrary = sanitize.runtimeLibrary + recoverySuffix
-		} else {
-			sanitize.androidMkRuntimeLibrary = sanitize.runtimeLibrary
-		}
-	}
-
 	blacklist := android.OptionalPathForModuleSrc(ctx, sanitize.Properties.Sanitize.Blacklist)
 	if blacklist.Valid() {
 		flags.CFlags = append(flags.CFlags, "-fsanitize-blacklist="+blacklist.String())
@@ -621,12 +510,6 @@
 }
 
 func (sanitize *sanitize) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
-	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
-		if sanitize.androidMkRuntimeLibrary != "" {
-			fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES += "+sanitize.androidMkRuntimeLibrary)
-		}
-	})
-
 	// Add a suffix for CFI-enabled static libraries to allow surfacing both to make without a
 	// name conflict.
 	if ret.Class == "STATIC_LIBRARIES" && Bool(sanitize.Properties.Sanitize.Cfi) {
@@ -782,6 +665,159 @@
 	}
 }
 
+// Add the dependency to the runtime library for each of the sanitizer variants
+func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
+	if mctx.Os() != android.Android {
+		return
+	}
+	if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
+		var sanitizers []string
+		var diagSanitizers []string
+
+		if Bool(c.sanitize.Properties.Sanitize.All_undefined) {
+			sanitizers = append(sanitizers, "undefined")
+		} else {
+			if Bool(c.sanitize.Properties.Sanitize.Undefined) {
+				sanitizers = append(sanitizers,
+					"bool",
+					"integer-divide-by-zero",
+					"return",
+					"returns-nonnull-attribute",
+					"shift-exponent",
+					"unreachable",
+					"vla-bound",
+					// TODO(danalbert): The following checks currently have compiler performance issues.
+					//"alignment",
+					//"bounds",
+					//"enum",
+					//"float-cast-overflow",
+					//"float-divide-by-zero",
+					//"nonnull-attribute",
+					//"null",
+					//"shift-base",
+					//"signed-integer-overflow",
+					// TODO(danalbert): Fix UB in libc++'s __tree so we can turn this on.
+					// https://llvm.org/PR19302
+					// http://reviews.llvm.org/D6974
+					// "object-size",
+				)
+			}
+			sanitizers = append(sanitizers, c.sanitize.Properties.Sanitize.Misc_undefined...)
+		}
+
+		if Bool(c.sanitize.Properties.Sanitize.Diag.Undefined) {
+			diagSanitizers = append(diagSanitizers, "undefined")
+		}
+
+		diagSanitizers = append(diagSanitizers, c.sanitize.Properties.Sanitize.Diag.Misc_undefined...)
+
+		if Bool(c.sanitize.Properties.Sanitize.Address) {
+			sanitizers = append(sanitizers, "address")
+			diagSanitizers = append(diagSanitizers, "address")
+		}
+
+		if Bool(c.sanitize.Properties.Sanitize.Hwaddress) {
+			sanitizers = append(sanitizers, "hwaddress")
+		}
+
+		if Bool(c.sanitize.Properties.Sanitize.Thread) {
+			sanitizers = append(sanitizers, "thread")
+		}
+
+		if Bool(c.sanitize.Properties.Sanitize.Safestack) {
+			sanitizers = append(sanitizers, "safe-stack")
+		}
+
+		if Bool(c.sanitize.Properties.Sanitize.Cfi) {
+			sanitizers = append(sanitizers, "cfi")
+
+			if Bool(c.sanitize.Properties.Sanitize.Diag.Cfi) {
+				diagSanitizers = append(diagSanitizers, "cfi")
+			}
+		}
+
+		if Bool(c.sanitize.Properties.Sanitize.Integer_overflow) {
+			sanitizers = append(sanitizers, "unsigned-integer-overflow")
+			sanitizers = append(sanitizers, "signed-integer-overflow")
+			if Bool(c.sanitize.Properties.Sanitize.Diag.Integer_overflow) {
+				diagSanitizers = append(diagSanitizers, "unsigned-integer-overflow")
+				diagSanitizers = append(diagSanitizers, "signed-integer-overflow")
+			}
+		}
+
+		if Bool(c.sanitize.Properties.Sanitize.Scudo) {
+			sanitizers = append(sanitizers, "scudo")
+		}
+
+		if Bool(c.sanitize.Properties.Sanitize.Scs) {
+			sanitizers = append(sanitizers, "shadow-call-stack")
+		}
+
+		// Save the list of sanitizers. These will be used again when generating
+		// the build rules (for Cflags, etc.)
+		c.sanitize.Properties.Sanitizers = sanitizers
+		c.sanitize.Properties.DiagSanitizers = diagSanitizers
+
+		// Determine the runtime library required
+		runtimeLibrary := ""
+		toolchain := c.toolchain(mctx)
+		if Bool(c.sanitize.Properties.Sanitize.Address) {
+			runtimeLibrary = config.AddressSanitizerRuntimeLibrary(toolchain)
+		} else if Bool(c.sanitize.Properties.Sanitize.Hwaddress) {
+			if c.staticBinary() {
+				runtimeLibrary = config.HWAddressSanitizerStaticLibrary(toolchain)
+			} else {
+				runtimeLibrary = config.HWAddressSanitizerRuntimeLibrary(toolchain)
+			}
+		} else if Bool(c.sanitize.Properties.Sanitize.Thread) {
+			runtimeLibrary = config.ThreadSanitizerRuntimeLibrary(toolchain)
+		} else if Bool(c.sanitize.Properties.Sanitize.Scudo) {
+			if len(diagSanitizers) == 0 && !c.sanitize.Properties.UbsanRuntimeDep {
+				runtimeLibrary = config.ScudoMinimalRuntimeLibrary(toolchain)
+			} else {
+				runtimeLibrary = config.ScudoRuntimeLibrary(toolchain)
+			}
+		} else if len(diagSanitizers) > 0 || c.sanitize.Properties.UbsanRuntimeDep {
+			runtimeLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain)
+		}
+
+		if mctx.Device() && runtimeLibrary != "" {
+			if inList(runtimeLibrary, llndkLibraries) && !c.static() {
+				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([]blueprint.Variation{
+					{Mutator: "link", Variation: "static"},
+					{Mutator: "arch", Variation: mctx.Target().String()},
+				}, staticDepTag, runtimeLibrary)
+			} else if !c.static() {
+				// dynamic executable andshared libs get shared runtime libs
+				mctx.AddFarVariationDependencies([]blueprint.Variation{
+					{Mutator: "link", Variation: "shared"},
+					{Mutator: "arch", Variation: mctx.Target().String()},
+				}, sharedDepTag, 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.
+		}
+	}
+}
+
+type Sanitizeable interface {
+	android.Module
+	IsSanitizerEnabled() bool
+}
+
 // Create sanitized variants for modules that need them
 func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
 	return func(mctx android.BottomUpMutatorContext) {
@@ -883,6 +919,9 @@
 				}
 			}
 			c.sanitize.Properties.SanitizeDep = false
+		} else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok && sanitizeable.IsSanitizerEnabled() {
+			// APEX modules fall here
+			mctx.CreateVariations(t.String())
 		}
 	}
 }