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())
}
}
}