diff --git a/cc/androidmk.go b/cc/androidmk.go index ce35b5c44..e0e543ff0 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -530,9 +530,9 @@ func (c *snapshotLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entrie entries.SubName = "" - if c.isSanitizerEnabled(cfi) { + if c.IsSanitizerEnabled(cfi) { entries.SubName += ".cfi" - } else if c.isSanitizerEnabled(Hwasan) { + } else if c.IsSanitizerEnabled(Hwasan) { entries.SubName += ".hwasan" } diff --git a/cc/linkable.go b/cc/linkable.go index 209939916..5b5b856ab 100644 --- a/cc/linkable.go +++ b/cc/linkable.go @@ -95,6 +95,18 @@ type Snapshottable interface { // IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt. IsSnapshotPrebuilt() bool + + // IsSnapshotSanitizer returns true if this snapshot module implements SnapshotSanitizer. + IsSnapshotSanitizer() bool + + // IsSnapshotSanitizerAvailable returns true if this snapshot module has a sanitizer source available (cfi, hwasan). + IsSnapshotSanitizerAvailable(t SanitizerType) bool + + // SetSnapshotSanitizerVariation sets the sanitizer variation type for this snapshot module. + SetSnapshotSanitizerVariation(t SanitizerType, enabled bool) + + // IsSnapshotUnsanitizedVariant returns true if this is the unsanitized snapshot module variant. + IsSnapshotUnsanitizedVariant() bool } // LinkableInterface is an interface for a type of module that is linkable in a C++ library. diff --git a/cc/sanitize.go b/cc/sanitize.go index 8eea7db7b..f37b5c7ad 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -1189,7 +1189,7 @@ func (s *sanitizerSplitMutator) markSanitizableApexesMutator(ctx android.TopDown if sanitizeable, ok := ctx.Module().(Sanitizeable); ok { enabled := sanitizeable.IsSanitizerEnabled(ctx.Config(), s.sanitizer.name()) ctx.VisitDirectDeps(func(dep android.Module) { - if c, ok := dep.(*Module); ok && c.sanitize.isSanitizerEnabled(s.sanitizer) { + if c, ok := dep.(PlatformSanitizeable); ok && c.IsSanitizerEnabled(s.sanitizer) { enabled = true } }) @@ -1243,12 +1243,10 @@ func (s *sanitizerSplitMutator) Split(ctx android.BaseModuleContext) []string { } } - if c, ok := ctx.Module().(*Module); ok { - //TODO: When Rust modules have vendor support, enable this path for PlatformSanitizeable - + if c, ok := ctx.Module().(LinkableInterface); ok { // Check if it's a snapshot module supporting sanitizer - if ss, ok := c.linker.(snapshotSanitizer); ok { - if ss.isSanitizerAvailable(s.sanitizer) { + if c.IsSnapshotSanitizer() { + if c.IsSnapshotSanitizerAvailable(s.sanitizer) { return []string{"", s.sanitizer.variationName()} } else { return []string{""} @@ -1280,8 +1278,8 @@ func (s *sanitizerSplitMutator) OutgoingTransition(ctx android.OutgoingTransitio func (s *sanitizerSplitMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string { if d, ok := ctx.Module().(PlatformSanitizeable); ok { - if dm, ok := ctx.Module().(*Module); ok { - if ss, ok := dm.linker.(snapshotSanitizer); ok && ss.isSanitizerAvailable(s.sanitizer) { + if dm, ok := ctx.Module().(LinkableInterface); ok { + if dm.IsSnapshotSanitizerAvailable(s.sanitizer) { return incomingVariation } } @@ -1396,19 +1394,19 @@ func (s *sanitizerSplitMutator) Mutate(mctx android.BottomUpMutatorContext, vari if sanitizerVariation { sanitizeable.AddSanitizerDependencies(mctx, s.sanitizer.name()) } - } else if c, ok := mctx.Module().(*Module); ok { - if ss, ok := c.linker.(snapshotSanitizer); ok && ss.isSanitizerAvailable(s.sanitizer) { - if !ss.isUnsanitizedVariant() { + } else if c, ok := mctx.Module().(LinkableInterface); ok { + if c.IsSnapshotSanitizerAvailable(s.sanitizer) { + if !c.IsSnapshotUnsanitizedVariant() { // Snapshot sanitizer may have only one variantion. // Skip exporting the module if it already has a sanitizer variation. c.SetPreventInstall() c.SetHideFromMake() return } - c.linker.(snapshotSanitizer).setSanitizerVariation(s.sanitizer, sanitizerVariation) + c.SetSnapshotSanitizerVariation(s.sanitizer, sanitizerVariation) // Export the static lib name to make - if c.static() && c.ExportedToMake() { + if c.Static() && c.ExportedToMake() { // use BaseModuleName which is the name for Make. if s.sanitizer == cfi { cfiStaticLibs(mctx.Config()).add(c, c.BaseModuleName()) @@ -1420,6 +1418,35 @@ func (s *sanitizerSplitMutator) Mutate(mctx android.BottomUpMutatorContext, vari } } +func (c *Module) IsSnapshotSanitizer() bool { + if _, ok := c.linker.(SnapshotSanitizer); ok { + return true + } + return false +} + +func (c *Module) IsSnapshotSanitizerAvailable(t SanitizerType) bool { + if ss, ok := c.linker.(SnapshotSanitizer); ok { + return ss.IsSanitizerAvailable(t) + } + return false +} + +func (c *Module) SetSnapshotSanitizerVariation(t SanitizerType, enabled bool) { + if ss, ok := c.linker.(SnapshotSanitizer); ok { + ss.SetSanitizerVariation(t, enabled) + } else { + panic(fmt.Errorf("Calling SetSnapshotSanitizerVariation on a non-snapshotLibraryDecorator: %s", c.Name())) + } +} + +func (c *Module) IsSnapshotUnsanitizedVariant() bool { + if ss, ok := c.linker.(SnapshotSanitizer); ok { + return ss.IsUnsanitizedVariant() + } + return false +} + func (c *Module) SanitizeNever() bool { return Bool(c.sanitize.Properties.SanitizeMutated.Never) } diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go index bb1331051..e29c446e7 100644 --- a/cc/snapshot_prebuilt.go +++ b/cc/snapshot_prebuilt.go @@ -403,11 +403,11 @@ type SnapshotLibraryProperties struct { Sanitize_minimal_dep *bool `android:"arch_variant"` } -type snapshotSanitizer interface { - isSanitizerAvailable(t SanitizerType) bool - setSanitizerVariation(t SanitizerType, enabled bool) - isSanitizerEnabled(t SanitizerType) bool - isUnsanitizedVariant() bool +type SnapshotSanitizer interface { + IsSanitizerAvailable(t SanitizerType) bool + SetSanitizerVariation(t SanitizerType, enabled bool) + IsSanitizerEnabled(t SanitizerType) bool + IsUnsanitizedVariant() bool } type snapshotLibraryDecorator struct { @@ -460,9 +460,9 @@ func (p *snapshotLibraryDecorator) link(ctx ModuleContext, flags Flags, deps Pat return p.libraryDecorator.link(ctx, flags, deps, objs) } - if p.isSanitizerEnabled(cfi) { + if p.IsSanitizerEnabled(cfi) { p.properties = p.sanitizerProperties.Cfi - } else if p.isSanitizerEnabled(Hwasan) { + } else if p.IsSanitizerEnabled(Hwasan) { p.properties = p.sanitizerProperties.Hwasan } @@ -526,9 +526,9 @@ func (p *snapshotLibraryDecorator) nativeCoverage() bool { return false } -var _ snapshotSanitizer = (*snapshotLibraryDecorator)(nil) +var _ SnapshotSanitizer = (*snapshotLibraryDecorator)(nil) -func (p *snapshotLibraryDecorator) isSanitizerAvailable(t SanitizerType) bool { +func (p *snapshotLibraryDecorator) IsSanitizerAvailable(t SanitizerType) bool { switch t { case cfi: return p.sanitizerProperties.Cfi.Src != nil @@ -539,23 +539,23 @@ func (p *snapshotLibraryDecorator) isSanitizerAvailable(t SanitizerType) bool { } } -func (p *snapshotLibraryDecorator) setSanitizerVariation(t SanitizerType, enabled bool) { - if !enabled || p.isSanitizerEnabled(t) { +func (p *snapshotLibraryDecorator) SetSanitizerVariation(t SanitizerType, enabled bool) { + if !enabled || p.IsSanitizerEnabled(t) { return } - if !p.isUnsanitizedVariant() { + if !p.IsUnsanitizedVariant() { panic(fmt.Errorf("snapshot Sanitizer must be one of Cfi or Hwasan but not both")) } p.sanitizerProperties.SanitizerVariation = t } -func (p *snapshotLibraryDecorator) isSanitizerEnabled(t SanitizerType) bool { +func (p *snapshotLibraryDecorator) IsSanitizerEnabled(t SanitizerType) bool { return p.sanitizerProperties.SanitizerVariation == t } -func (p *snapshotLibraryDecorator) isUnsanitizedVariant() bool { - return !p.isSanitizerEnabled(Asan) && - !p.isSanitizerEnabled(Hwasan) +func (p *snapshotLibraryDecorator) IsUnsanitizedVariant() bool { + return !p.IsSanitizerEnabled(Asan) && + !p.IsSanitizerEnabled(Hwasan) } func snapshotLibraryFactory(image SnapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) { diff --git a/rust/config/global.go b/rust/config/global.go index ca2c9af83..4bd495d86 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -54,11 +54,11 @@ var ( "-C symbol-mangling-version=v0", "--color always", "-Zdylib-lto", + "-Z link-native-libraries=no", } deviceGlobalRustFlags = []string{ "-C panic=abort", - "-Z link-native-libraries=no", // Generate additional debug info for AutoFDO "-Z debug-info-for-profiling", } diff --git a/rust/fuzz.go b/rust/fuzz.go index 235f51779..4c04ce829 100644 --- a/rust/fuzz.go +++ b/rust/fuzz.go @@ -60,6 +60,25 @@ func NewRustFuzz(hod android.HostOrDeviceSupported) (*Module, *fuzzDecorator) { fuzz.binaryDecorator.baseCompiler.dir64 = "fuzz" fuzz.binaryDecorator.baseCompiler.location = InstallInData module.sanitize.SetSanitizer(cc.Fuzzer, true) + + // The fuzzer runtime is not present for darwin or bionic host modules, so disable rust_fuzz modules for these. + android.AddLoadHook(module, func(ctx android.LoadHookContext) { + + extraProps := struct { + Target struct { + Darwin struct { + Enabled *bool + } + Linux_bionic struct { + Enabled *bool + } + } + }{} + extraProps.Target.Darwin.Enabled = cc.BoolPtr(false) + extraProps.Target.Linux_bionic.Enabled = cc.BoolPtr(false) + ctx.AppendProperties(&extraProps) + }) + module.compiler = fuzz return module, fuzz } diff --git a/rust/snapshot_prebuilt.go b/rust/snapshot_prebuilt.go index 32d391629..42e3cef38 100644 --- a/rust/snapshot_prebuilt.go +++ b/rust/snapshot_prebuilt.go @@ -15,6 +15,8 @@ package rust import ( + "fmt" + "android/soong/android" "android/soong/cc" @@ -26,17 +28,80 @@ type snapshotLibraryDecorator struct { *libraryDecorator properties cc.SnapshotLibraryProperties sanitizerProperties struct { - CfiEnabled bool `blueprint:"mutated"` + SanitizerVariation cc.SanitizerType `blueprint:"mutated"` - // Library flags for cfi variant. - Cfi cc.SnapshotLibraryProperties `android:"arch_variant"` + //TODO: Library flags for cfi variant when CFI is supported. + //Cfi cc.SnapshotLibraryProperties `android:"arch_variant"` + + // Library flags for hwasan variant. + Hwasan cc.SnapshotLibraryProperties `android:"arch_variant"` } } +var _ cc.SnapshotSanitizer = (*snapshotLibraryDecorator)(nil) + +func (library *snapshotLibraryDecorator) IsSanitizerAvailable(t cc.SanitizerType) bool { + switch t { + //TODO: When CFI is supported, add a check here as well + case cc.Hwasan: + return library.sanitizerProperties.Hwasan.Src != nil + default: + return false + } +} + +func (library *snapshotLibraryDecorator) SetSanitizerVariation(t cc.SanitizerType, enabled bool) { + if !enabled || library.IsSanitizerEnabled(t) { + return + } + if !library.IsUnsanitizedVariant() { + panic(fmt.Errorf("snapshot Sanitizer must be one of Cfi or Hwasan but not both")) + } + library.sanitizerProperties.SanitizerVariation = t +} + +func (library *snapshotLibraryDecorator) IsSanitizerEnabled(t cc.SanitizerType) bool { + return library.sanitizerProperties.SanitizerVariation == t +} + +func (library *snapshotLibraryDecorator) IsUnsanitizedVariant() bool { + //TODO: When CFI is supported, add a check here as well + return !library.IsSanitizerEnabled(cc.Hwasan) +} + func init() { registerRustSnapshotModules(android.InitRegistrationContext) } +func (mod *Module) IsSnapshotSanitizerAvailable(t cc.SanitizerType) bool { + if ss, ok := mod.compiler.(cc.SnapshotSanitizer); ok { + return ss.IsSanitizerAvailable(t) + } + return false +} + +func (mod *Module) SetSnapshotSanitizerVariation(t cc.SanitizerType, enabled bool) { + if ss, ok := mod.compiler.(cc.SnapshotSanitizer); ok { + ss.SetSanitizerVariation(t, enabled) + } else { + panic(fmt.Errorf("Calling SetSnapshotSanitizerVariation on a non-snapshotLibraryDecorator: %s", mod.Name())) + } +} + +func (mod *Module) IsSnapshotUnsanitizedVariant() bool { + if ss, ok := mod.compiler.(cc.SnapshotSanitizer); ok { + return ss.IsUnsanitizedVariant() + } + return false +} + +func (mod *Module) IsSnapshotSanitizer() bool { + if _, ok := mod.compiler.(cc.SnapshotSanitizer); ok { + return true + } + return false +} + func registerRustSnapshotModules(ctx android.RegistrationContext) { cc.VendorSnapshotImageSingleton.RegisterAdditionalModule(ctx, "vendor_snapshot_rlib", VendorSnapshotRlibFactory) @@ -81,6 +146,9 @@ func (library *snapshotLibraryDecorator) compile(ctx ModuleContext, flags Flags, library.SetSnapshotAndroidMkSuffix(ctx, variant) + if library.IsSanitizerEnabled(cc.Hwasan) { + library.properties = library.sanitizerProperties.Hwasan + } if !library.MatchesWithDevice(ctx.DeviceConfig()) { return buildOutput{} }