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:
@@ -530,9 +530,9 @@ func (c *snapshotLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entrie
|
|||||||
|
|
||||||
entries.SubName = ""
|
entries.SubName = ""
|
||||||
|
|
||||||
if c.isSanitizerEnabled(cfi) {
|
if c.IsSanitizerEnabled(cfi) {
|
||||||
entries.SubName += ".cfi"
|
entries.SubName += ".cfi"
|
||||||
} else if c.isSanitizerEnabled(Hwasan) {
|
} else if c.IsSanitizerEnabled(Hwasan) {
|
||||||
entries.SubName += ".hwasan"
|
entries.SubName += ".hwasan"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -95,6 +95,18 @@ type Snapshottable interface {
|
|||||||
|
|
||||||
// IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
|
// IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
|
||||||
IsSnapshotPrebuilt() bool
|
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.
|
// 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 {
|
if sanitizeable, ok := ctx.Module().(Sanitizeable); ok {
|
||||||
enabled := sanitizeable.IsSanitizerEnabled(ctx.Config(), s.sanitizer.name())
|
enabled := sanitizeable.IsSanitizerEnabled(ctx.Config(), s.sanitizer.name())
|
||||||
ctx.VisitDirectDeps(func(dep android.Module) {
|
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
|
enabled = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -1243,12 +1243,10 @@ func (s *sanitizerSplitMutator) Split(ctx android.BaseModuleContext) []string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c, ok := ctx.Module().(*Module); ok {
|
if c, ok := ctx.Module().(LinkableInterface); ok {
|
||||||
//TODO: When Rust modules have vendor support, enable this path for PlatformSanitizeable
|
|
||||||
|
|
||||||
// Check if it's a snapshot module supporting sanitizer
|
// Check if it's a snapshot module supporting sanitizer
|
||||||
if ss, ok := c.linker.(snapshotSanitizer); ok {
|
if c.IsSnapshotSanitizer() {
|
||||||
if ss.isSanitizerAvailable(s.sanitizer) {
|
if c.IsSnapshotSanitizerAvailable(s.sanitizer) {
|
||||||
return []string{"", s.sanitizer.variationName()}
|
return []string{"", s.sanitizer.variationName()}
|
||||||
} else {
|
} else {
|
||||||
return []string{""}
|
return []string{""}
|
||||||
@@ -1280,8 +1278,8 @@ func (s *sanitizerSplitMutator) OutgoingTransition(ctx android.OutgoingTransitio
|
|||||||
|
|
||||||
func (s *sanitizerSplitMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
|
func (s *sanitizerSplitMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
|
||||||
if d, ok := ctx.Module().(PlatformSanitizeable); ok {
|
if d, ok := ctx.Module().(PlatformSanitizeable); ok {
|
||||||
if dm, ok := ctx.Module().(*Module); ok {
|
if dm, ok := ctx.Module().(LinkableInterface); ok {
|
||||||
if ss, ok := dm.linker.(snapshotSanitizer); ok && ss.isSanitizerAvailable(s.sanitizer) {
|
if dm.IsSnapshotSanitizerAvailable(s.sanitizer) {
|
||||||
return incomingVariation
|
return incomingVariation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1396,19 +1394,19 @@ func (s *sanitizerSplitMutator) Mutate(mctx android.BottomUpMutatorContext, vari
|
|||||||
if sanitizerVariation {
|
if sanitizerVariation {
|
||||||
sanitizeable.AddSanitizerDependencies(mctx, s.sanitizer.name())
|
sanitizeable.AddSanitizerDependencies(mctx, s.sanitizer.name())
|
||||||
}
|
}
|
||||||
} else if c, ok := mctx.Module().(*Module); ok {
|
} else if c, ok := mctx.Module().(LinkableInterface); ok {
|
||||||
if ss, ok := c.linker.(snapshotSanitizer); ok && ss.isSanitizerAvailable(s.sanitizer) {
|
if c.IsSnapshotSanitizerAvailable(s.sanitizer) {
|
||||||
if !ss.isUnsanitizedVariant() {
|
if !c.IsSnapshotUnsanitizedVariant() {
|
||||||
// Snapshot sanitizer may have only one variantion.
|
// Snapshot sanitizer may have only one variantion.
|
||||||
// Skip exporting the module if it already has a sanitizer variation.
|
// Skip exporting the module if it already has a sanitizer variation.
|
||||||
c.SetPreventInstall()
|
c.SetPreventInstall()
|
||||||
c.SetHideFromMake()
|
c.SetHideFromMake()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.linker.(snapshotSanitizer).setSanitizerVariation(s.sanitizer, sanitizerVariation)
|
c.SetSnapshotSanitizerVariation(s.sanitizer, sanitizerVariation)
|
||||||
|
|
||||||
// Export the static lib name to make
|
// 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.
|
// use BaseModuleName which is the name for Make.
|
||||||
if s.sanitizer == cfi {
|
if s.sanitizer == cfi {
|
||||||
cfiStaticLibs(mctx.Config()).add(c, c.BaseModuleName())
|
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 {
|
func (c *Module) SanitizeNever() bool {
|
||||||
return Bool(c.sanitize.Properties.SanitizeMutated.Never)
|
return Bool(c.sanitize.Properties.SanitizeMutated.Never)
|
||||||
}
|
}
|
||||||
|
@@ -403,11 +403,11 @@ type SnapshotLibraryProperties struct {
|
|||||||
Sanitize_minimal_dep *bool `android:"arch_variant"`
|
Sanitize_minimal_dep *bool `android:"arch_variant"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type snapshotSanitizer interface {
|
type SnapshotSanitizer interface {
|
||||||
isSanitizerAvailable(t SanitizerType) bool
|
IsSanitizerAvailable(t SanitizerType) bool
|
||||||
setSanitizerVariation(t SanitizerType, enabled bool)
|
SetSanitizerVariation(t SanitizerType, enabled bool)
|
||||||
isSanitizerEnabled(t SanitizerType) bool
|
IsSanitizerEnabled(t SanitizerType) bool
|
||||||
isUnsanitizedVariant() bool
|
IsUnsanitizedVariant() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type snapshotLibraryDecorator struct {
|
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)
|
return p.libraryDecorator.link(ctx, flags, deps, objs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.isSanitizerEnabled(cfi) {
|
if p.IsSanitizerEnabled(cfi) {
|
||||||
p.properties = p.sanitizerProperties.Cfi
|
p.properties = p.sanitizerProperties.Cfi
|
||||||
} else if p.isSanitizerEnabled(Hwasan) {
|
} else if p.IsSanitizerEnabled(Hwasan) {
|
||||||
p.properties = p.sanitizerProperties.Hwasan
|
p.properties = p.sanitizerProperties.Hwasan
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -526,9 +526,9 @@ func (p *snapshotLibraryDecorator) nativeCoverage() bool {
|
|||||||
return false
|
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 {
|
switch t {
|
||||||
case cfi:
|
case cfi:
|
||||||
return p.sanitizerProperties.Cfi.Src != nil
|
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) {
|
func (p *snapshotLibraryDecorator) SetSanitizerVariation(t SanitizerType, enabled bool) {
|
||||||
if !enabled || p.isSanitizerEnabled(t) {
|
if !enabled || p.IsSanitizerEnabled(t) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !p.isUnsanitizedVariant() {
|
if !p.IsUnsanitizedVariant() {
|
||||||
panic(fmt.Errorf("snapshot Sanitizer must be one of Cfi or Hwasan but not both"))
|
panic(fmt.Errorf("snapshot Sanitizer must be one of Cfi or Hwasan but not both"))
|
||||||
}
|
}
|
||||||
p.sanitizerProperties.SanitizerVariation = t
|
p.sanitizerProperties.SanitizerVariation = t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *snapshotLibraryDecorator) isSanitizerEnabled(t SanitizerType) bool {
|
func (p *snapshotLibraryDecorator) IsSanitizerEnabled(t SanitizerType) bool {
|
||||||
return p.sanitizerProperties.SanitizerVariation == t
|
return p.sanitizerProperties.SanitizerVariation == t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *snapshotLibraryDecorator) isUnsanitizedVariant() bool {
|
func (p *snapshotLibraryDecorator) IsUnsanitizedVariant() bool {
|
||||||
return !p.isSanitizerEnabled(Asan) &&
|
return !p.IsSanitizerEnabled(Asan) &&
|
||||||
!p.isSanitizerEnabled(Hwasan)
|
!p.IsSanitizerEnabled(Hwasan)
|
||||||
}
|
}
|
||||||
|
|
||||||
func snapshotLibraryFactory(image SnapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) {
|
func snapshotLibraryFactory(image SnapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) {
|
||||||
|
@@ -54,11 +54,11 @@ var (
|
|||||||
"-C symbol-mangling-version=v0",
|
"-C symbol-mangling-version=v0",
|
||||||
"--color always",
|
"--color always",
|
||||||
"-Zdylib-lto",
|
"-Zdylib-lto",
|
||||||
|
"-Z link-native-libraries=no",
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceGlobalRustFlags = []string{
|
deviceGlobalRustFlags = []string{
|
||||||
"-C panic=abort",
|
"-C panic=abort",
|
||||||
"-Z link-native-libraries=no",
|
|
||||||
// Generate additional debug info for AutoFDO
|
// Generate additional debug info for AutoFDO
|
||||||
"-Z debug-info-for-profiling",
|
"-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.dir64 = "fuzz"
|
||||||
fuzz.binaryDecorator.baseCompiler.location = InstallInData
|
fuzz.binaryDecorator.baseCompiler.location = InstallInData
|
||||||
module.sanitize.SetSanitizer(cc.Fuzzer, true)
|
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
|
module.compiler = fuzz
|
||||||
return module, fuzz
|
return module, fuzz
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
package rust
|
package rust
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/cc"
|
"android/soong/cc"
|
||||||
|
|
||||||
@@ -26,17 +28,80 @@ type snapshotLibraryDecorator struct {
|
|||||||
*libraryDecorator
|
*libraryDecorator
|
||||||
properties cc.SnapshotLibraryProperties
|
properties cc.SnapshotLibraryProperties
|
||||||
sanitizerProperties struct {
|
sanitizerProperties struct {
|
||||||
CfiEnabled bool `blueprint:"mutated"`
|
SanitizerVariation cc.SanitizerType `blueprint:"mutated"`
|
||||||
|
|
||||||
// Library flags for cfi variant.
|
//TODO: Library flags for cfi variant when CFI is supported.
|
||||||
Cfi cc.SnapshotLibraryProperties `android:"arch_variant"`
|
//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() {
|
func init() {
|
||||||
registerRustSnapshotModules(android.InitRegistrationContext)
|
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) {
|
func registerRustSnapshotModules(ctx android.RegistrationContext) {
|
||||||
cc.VendorSnapshotImageSingleton.RegisterAdditionalModule(ctx,
|
cc.VendorSnapshotImageSingleton.RegisterAdditionalModule(ctx,
|
||||||
"vendor_snapshot_rlib", VendorSnapshotRlibFactory)
|
"vendor_snapshot_rlib", VendorSnapshotRlibFactory)
|
||||||
@@ -81,6 +146,9 @@ func (library *snapshotLibraryDecorator) compile(ctx ModuleContext, flags Flags,
|
|||||||
|
|
||||||
library.SetSnapshotAndroidMkSuffix(ctx, variant)
|
library.SetSnapshotAndroidMkSuffix(ctx, variant)
|
||||||
|
|
||||||
|
if library.IsSanitizerEnabled(cc.Hwasan) {
|
||||||
|
library.properties = library.sanitizerProperties.Hwasan
|
||||||
|
}
|
||||||
if !library.MatchesWithDevice(ctx.DeviceConfig()) {
|
if !library.MatchesWithDevice(ctx.DeviceConfig()) {
|
||||||
return buildOutput{}
|
return buildOutput{}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user