rust: Rust sanitized snapshots variations
This adds support for correctly handling Rust sanitized snapshots, ensuring they only have one variation. The presence of multiple variations were causing build failures when a rust_fuzz module for host was defined and a snapshot build was requested. This also sets -Z link-native-libraries=no on host modules (in addition to device modules) to avoid emitting extra linkage flags due to link attributes. Bug: 282897366 Test: SOONG_SDK_SNAPSHOT_USE_SRCJAR=true m Change-Id: Idf980c29145f11c530ad635a4eb5b01a1730ac24
This commit is contained in:
parent
4e6c42d417
commit
5467a39984
7 changed files with 161 additions and 35 deletions
|
@ -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"
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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",
|
||||
}
|
||||
|
|
19
rust/fuzz.go
19
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
|
||||
}
|
||||
|
|
|
@ -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{}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue