rust: Add HWASan build support

HWASan for static Rust executables is not supported yet.

Bug: 180495975
Test: build local test app with HWASan
Change-Id: I46e851c82a16943586ec3a789f09a58651d036e3
This commit is contained in:
Tri Vo
2021-04-01 13:59:27 -07:00
parent 6eafc36e60
commit 0a74c3e06e
2 changed files with 74 additions and 7 deletions

View File

@@ -70,6 +70,11 @@ func (mod *Module) AndroidMkEntries() []android.AndroidMkEntries {
// If the compiler is disabled, this is a SourceProvider.
mod.SubAndroidMk(&ret, mod.sourceProvider)
}
if mod.sanitize != nil {
mod.SubAndroidMk(&ret, mod.sanitize)
}
ret.SubName += mod.Properties.SubName
return []android.AndroidMkEntries{ret}

View File

@@ -23,11 +23,12 @@ import (
)
type SanitizeProperties struct {
// enable AddressSanitizer, ThreadSanitizer, or UndefinedBehaviorSanitizer
// enable AddressSanitizer, HWAddressSanitizer, and others.
Sanitize struct {
Address *bool `android:"arch_variant"`
Fuzzer *bool `android:"arch_variant"`
Never *bool `android:"arch_variant"`
Address *bool `android:"arch_variant"`
Hwaddress *bool `android:"arch_variant"`
Fuzzer *bool `android:"arch_variant"`
Never *bool `android:"arch_variant"`
}
SanitizerEnabled bool `blueprint:"mutated"`
SanitizeDep bool `blueprint:"mutated"`
@@ -57,6 +58,11 @@ var asanFlags = []string{
"-Z sanitizer=address",
}
var hwasanFlags = []string{
"-Z sanitizer=hwaddress",
"-C target-feature=+tagged-globals",
}
func boolPtr(v bool) *bool {
if v {
return &v
@@ -83,6 +89,15 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
if ctx.Os() == android.Android && Bool(s.Address) {
sanitize.Properties.SanitizerEnabled = true
}
// HWASan requires AArch64 hardware feature (top-byte-ignore).
if ctx.Arch().ArchType != android.Arm64 {
s.Hwaddress = nil
}
if ctx.Os() == android.Android && Bool(s.Hwaddress) {
sanitize.Properties.SanitizerEnabled = true
}
}
type sanitize struct {
@@ -99,6 +114,9 @@ func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags, deps PathDeps) (
if Bool(sanitize.Properties.Sanitize.Address) {
flags.RustFlags = append(flags.RustFlags, asanFlags...)
}
if Bool(sanitize.Properties.Sanitize.Hwaddress) {
flags.RustFlags = append(flags.RustFlags, hwasanFlags...)
}
return flags, deps
}
@@ -111,11 +129,38 @@ func rustSanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
if !mod.Enabled() {
return
}
variations := mctx.Target().Variations()
var depTag blueprint.DependencyTag
var deps []string
if Bool(mod.sanitize.Properties.Sanitize.Fuzzer) || Bool(mod.sanitize.Properties.Sanitize.Address) {
mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
{Mutator: "link", Variation: "shared"},
}...), cc.SharedDepTag(), config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan"))
variations = append(variations,
blueprint.Variation{Mutator: "link", Variation: "shared"})
depTag = cc.SharedDepTag()
deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan")}
} else if mod.IsSanitizerEnabled(cc.Hwasan) {
// TODO(b/180495975): HWASan for static Rust binaries isn't supported yet.
if binary, ok := mod.compiler.(*binaryDecorator); ok {
if Bool(binary.Properties.Static_executable) {
mctx.ModuleErrorf("HWASan is not supported for static Rust executables yet.")
}
}
if mod.StaticallyLinked() {
variations = append(variations,
blueprint.Variation{Mutator: "link", Variation: "static"})
depTag = cc.StaticDepTag(false)
deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "hwasan_static")}
} else {
variations = append(variations,
blueprint.Variation{Mutator: "link", Variation: "shared"})
depTag = cc.SharedDepTag()
deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "hwasan")}
}
}
mctx.AddFarVariationDependencies(variations, depTag, deps...)
}
}
@@ -128,6 +173,9 @@ func (sanitize *sanitize) SetSanitizer(t cc.SanitizerType, b bool) {
case cc.Asan:
sanitize.Properties.Sanitize.Address = boolPtr(b)
sanitizerSet = true
case cc.Hwasan:
sanitize.Properties.Sanitize.Hwaddress = boolPtr(b)
sanitizerSet = true
default:
panic(fmt.Errorf("setting unsupported sanitizerType %d", t))
}
@@ -169,11 +217,23 @@ func (sanitize *sanitize) getSanitizerBoolPtr(t cc.SanitizerType) *bool {
return sanitize.Properties.Sanitize.Fuzzer
case cc.Asan:
return sanitize.Properties.Sanitize.Address
case cc.Hwasan:
return sanitize.Properties.Sanitize.Hwaddress
default:
return nil
}
}
func (sanitize *sanitize) AndroidMk(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
// Add a suffix for hwasan rlib libraries to allow surfacing both the sanitized and
// non-sanitized variants to make without a name conflict.
if entries.Class == "RLIB_LIBRARIES" || entries.Class == "STATIC_LIBRARIES" {
if sanitize.isSanitizerEnabled(cc.Hwasan) {
entries.SubName += ".hwasan"
}
}
}
func (mod *Module) SanitizerSupported(t cc.SanitizerType) bool {
if mod.Host() {
return false
@@ -183,6 +243,8 @@ func (mod *Module) SanitizerSupported(t cc.SanitizerType) bool {
return true
case cc.Asan:
return true
case cc.Hwasan:
return true
default:
return false
}