Fix ASAN mutator.

This CL fixes a bug in the ASAN top down mutator which was incorrectly
checking (and setting) SanitizeDep to true only for the parent module
and not for the visited child modules.

Fixing this also requires some changes to the variant creation logic
to ensure that the correct variant is passed to make for
installation. This will eventually be replaced by logic that appends
an appropriate suffix to sanitized libraries (eg: libc++.asan), which
will allow both variants to be passed to make.

Bug: 64536751
Test: m -j40 && SANITIZE_TARGET="address" m -j40
Change-Id: Id5e5a5946192adf07418dd433bca503047177007
This commit is contained in:
Vishwath Mohan 2017-08-02 14:18:08 -07:00
parent 998d9eb6b9
commit 12758d0cec

View file

@ -457,23 +457,6 @@ func (sanitize *sanitize) inSanitizerDir() bool {
return sanitize.Properties.InSanitizerDir
}
func (sanitize *sanitize) Sanitizer(t sanitizerType) bool {
if sanitize == nil {
return false
}
switch t {
case asan:
return Bool(sanitize.Properties.Sanitize.Address)
case tsan:
return Bool(sanitize.Properties.Sanitize.Thread)
case intOverflow:
return Bool(sanitize.Properties.Sanitize.Integer_overflow)
default:
panic(fmt.Errorf("unknown sanitizerType %d", t))
}
}
func (sanitize *sanitize) SetSanitizer(t sanitizerType, b bool) {
switch t {
case asan:
@ -493,13 +476,47 @@ func (sanitize *sanitize) SetSanitizer(t sanitizerType, b bool) {
}
}
func (sanitize *sanitize) getSanitizerBoolPtr(t sanitizerType) *bool {
switch t {
case asan:
return sanitize.Properties.Sanitize.Address
case tsan:
return sanitize.Properties.Sanitize.Thread
case intOverflow:
return sanitize.Properties.Sanitize.Integer_overflow
default:
panic(fmt.Errorf("unknown sanitizerType %d", t))
}
}
// Check if the sanitizer is explicitly disabled (as opposed to nil by
// virtue of not being set).
func (sanitize *sanitize) isSanitizerExplicitlyDisabled(t sanitizerType) bool {
if sanitize == nil {
return false
}
sanitizerVal := sanitize.getSanitizerBoolPtr(t)
return sanitizerVal != nil && *sanitizerVal == false
}
func (sanitize *sanitize) isSanitizerExplicitlyEnabled(t sanitizerType) bool {
if sanitize == nil {
return false
}
sanitizerVal := sanitize.getSanitizerBoolPtr(t)
return sanitizerVal != nil && *sanitizerVal == true
}
// Propagate asan requirements down from binaries
func sanitizerDepsMutator(t sanitizerType) func(android.TopDownMutatorContext) {
return func(mctx android.TopDownMutatorContext) {
if c, ok := mctx.Module().(*Module); ok && c.sanitize.Sanitizer(t) {
if c, ok := mctx.Module().(*Module); ok && c.sanitize.isSanitizerExplicitlyEnabled(t) {
mctx.VisitDepsDepthFirst(func(module blueprint.Module) {
if d, ok := mctx.Module().(*Module); ok && c.sanitize != nil &&
!c.sanitize.Properties.Sanitize.Never {
if d, ok := module.(*Module); ok && d.sanitize != nil &&
!d.sanitize.Properties.Sanitize.Never &&
!d.sanitize.isSanitizerExplicitlyDisabled(t) {
d.sanitize.Properties.SanitizeDep = true
}
})
@ -511,10 +528,10 @@ func sanitizerDepsMutator(t sanitizerType) func(android.TopDownMutatorContext) {
func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
return func(mctx android.BottomUpMutatorContext) {
if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
if c.isDependencyRoot() && c.sanitize.Sanitizer(t) {
if c.isDependencyRoot() && c.sanitize.isSanitizerExplicitlyEnabled(t) {
modules := mctx.CreateVariations(t.String())
modules[0].(*Module).sanitize.SetSanitizer(t, true)
} else if c.sanitize.Properties.SanitizeDep {
} else if c.sanitize.isSanitizerExplicitlyEnabled(t) || c.sanitize.Properties.SanitizeDep {
modules := mctx.CreateVariations("", t.String())
modules[0].(*Module).sanitize.SetSanitizer(t, false)
modules[1].(*Module).sanitize.SetSanitizer(t, true)
@ -523,10 +540,18 @@ func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
if mctx.Device() {
modules[1].(*Module).sanitize.Properties.InSanitizerDir = true
} else {
modules[0].(*Module).Properties.PreventInstall = true
if c.sanitize.isSanitizerExplicitlyEnabled(t) {
modules[0].(*Module).Properties.PreventInstall = true
} else {
modules[1].(*Module).Properties.PreventInstall = true
}
}
if mctx.AConfig().EmbeddedInMake() {
modules[0].(*Module).Properties.HideFromMake = true
if c.sanitize.isSanitizerExplicitlyEnabled(t) {
modules[0].(*Module).Properties.HideFromMake = true
} else {
modules[1].(*Module).Properties.HideFromMake = true
}
}
}
c.sanitize.Properties.SanitizeDep = false