Merge changes from topic "cfi_vendor_snapshot"

* changes:
  Add cfi static libraries to vendor snapshot
  Refactor vendor snapshot modules
This commit is contained in:
Inseob Kim
2020-08-07 01:48:10 +00:00
committed by Gerrit Code Review
5 changed files with 264 additions and 167 deletions

View File

@@ -518,10 +518,14 @@ func (c *vendorSnapshotLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext,
entries.Class = "HEADER_LIBRARIES" entries.Class = "HEADER_LIBRARIES"
} }
entries.SubName = ""
if c.sanitizerProperties.CfiEnabled {
entries.SubName += ".cfi"
}
if c.androidMkVendorSuffix { if c.androidMkVendorSuffix {
entries.SubName = vendorSuffix entries.SubName += vendorSuffix
} else {
entries.SubName = ""
} }
entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) { entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {

View File

@@ -1013,17 +1013,25 @@ func TestVendorSnapshot(t *testing.T) {
filepath.Join(sharedDir, "libvendor_available.so.json")) filepath.Join(sharedDir, "libvendor_available.so.json"))
// For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured. // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
// Also cfi variants are captured, except for prebuilts like toolchain_library
staticVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static", archType, archVariant) staticVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static", archType, archVariant)
staticCfiVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static_cfi", archType, archVariant)
staticDir := filepath.Join(snapshotVariantPath, archDir, "static") staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant) checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant) checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant)
checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.cfi.a", staticDir, staticCfiVariant)
checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant) checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant)
checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.cfi.a", staticDir, staticCfiVariant)
checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant) checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant)
checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.cfi.a", staticDir, staticCfiVariant)
jsonFiles = append(jsonFiles, jsonFiles = append(jsonFiles,
filepath.Join(staticDir, "libb.a.json"), filepath.Join(staticDir, "libb.a.json"),
filepath.Join(staticDir, "libvndk.a.json"), filepath.Join(staticDir, "libvndk.a.json"),
filepath.Join(staticDir, "libvndk.cfi.a.json"),
filepath.Join(staticDir, "libvendor.a.json"), filepath.Join(staticDir, "libvendor.a.json"),
filepath.Join(staticDir, "libvendor_available.a.json")) filepath.Join(staticDir, "libvendor.cfi.a.json"),
filepath.Join(staticDir, "libvendor_available.a.json"),
filepath.Join(staticDir, "libvendor_available.cfi.a.json"))
// For binary executables, all vendor:true and vendor_available modules are captured. // For binary executables, all vendor:true and vendor_available modules are captured.
if archType == "arm64" { if archType == "arm64" {
@@ -1055,6 +1063,39 @@ func TestVendorSnapshot(t *testing.T) {
} }
} }
func TestVendorSnapshotSanitizer(t *testing.T) {
bp := `
vendor_snapshot_static {
name: "libsnapshot",
vendor: true,
target_arch: "arm64",
version: "BOARD",
arch: {
arm64: {
src: "libsnapshot.a",
cfi: {
src: "libsnapshot.cfi.a",
}
},
},
}
`
config := TestConfig(buildDir, android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
ctx := testCcWithConfig(t, config)
// Check non-cfi and cfi variant.
staticVariant := "android_vendor.BOARD_arm64_armv8-a_static"
staticCfiVariant := "android_vendor.BOARD_arm64_armv8-a_static_cfi"
staticModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticVariant).Module().(*Module)
assertString(t, staticModule.outputFile.Path().Base(), "libsnapshot.a")
staticCfiModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticCfiVariant).Module().(*Module)
assertString(t, staticCfiModule.outputFile.Path().Base(), "libsnapshot.cfi.a")
}
func TestDoubleLoadableDepError(t *testing.T) { func TestDoubleLoadableDepError(t *testing.T) {
// Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib. // Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", ` testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `

View File

@@ -321,14 +321,14 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
// Is CFI actually enabled? // Is CFI actually enabled?
if !ctx.Config().EnableCFI() { if !ctx.Config().EnableCFI() {
s.Cfi = nil s.Cfi = boolPtr(false)
s.Diag.Cfi = nil s.Diag.Cfi = boolPtr(false)
} }
// Also disable CFI for arm32 until b/35157333 is fixed. // Also disable CFI for arm32 until b/35157333 is fixed.
if ctx.Arch().ArchType == android.Arm { if ctx.Arch().ArchType == android.Arm {
s.Cfi = nil s.Cfi = boolPtr(false)
s.Diag.Cfi = nil s.Diag.Cfi = boolPtr(false)
} }
// HWASan requires AArch64 hardware feature (top-byte-ignore). // HWASan requires AArch64 hardware feature (top-byte-ignore).
@@ -343,14 +343,14 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
// Also disable CFI if ASAN is enabled. // Also disable CFI if ASAN is enabled.
if Bool(s.Address) || Bool(s.Hwaddress) { if Bool(s.Address) || Bool(s.Hwaddress) {
s.Cfi = nil s.Cfi = boolPtr(false)
s.Diag.Cfi = nil s.Diag.Cfi = boolPtr(false)
} }
// Disable sanitizers that depend on the UBSan runtime for windows/darwin builds. // Disable sanitizers that depend on the UBSan runtime for windows/darwin builds.
if !ctx.Os().Linux() { if !ctx.Os().Linux() {
s.Cfi = nil s.Cfi = boolPtr(false)
s.Diag.Cfi = nil s.Diag.Cfi = boolPtr(false)
s.Misc_undefined = nil s.Misc_undefined = nil
s.Undefined = nil s.Undefined = nil
s.All_undefined = nil s.All_undefined = nil
@@ -359,14 +359,15 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
// Also disable CFI for VNDK variants of components // Also disable CFI for VNDK variants of components
if ctx.isVndk() && ctx.useVndk() { if ctx.isVndk() && ctx.useVndk() {
s.Cfi = nil if ctx.static() {
s.Diag.Cfi = nil // Cfi variant for static vndk should be captured as vendor snapshot,
} // so don't strictly disable Cfi.
s.Cfi = nil
// Also disable CFI if building against snapshot. s.Diag.Cfi = nil
vndkVersion := ctx.DeviceConfig().VndkVersion() } else {
if ctx.useVndk() && vndkVersion != "current" && vndkVersion != "" { s.Cfi = boolPtr(false)
s.Cfi = nil s.Diag.Cfi = boolPtr(false)
}
} }
// HWASan ramdisk (which is built from recovery) goes over some bootloader limit. // HWASan ramdisk (which is built from recovery) goes over some bootloader limit.
@@ -411,7 +412,7 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) {
// TODO(b/131771163): CFI transiently depends on LTO, and thus Fuzzer is // TODO(b/131771163): CFI transiently depends on LTO, and thus Fuzzer is
// mutually incompatible. // mutually incompatible.
if Bool(s.Fuzzer) { if Bool(s.Fuzzer) {
s.Cfi = nil s.Cfi = boolPtr(false)
} }
} }
@@ -741,27 +742,64 @@ func isSanitizableDependencyTag(tag blueprint.DependencyTag) bool {
} }
} }
// Determines if the current module is a static library going to be captured
// as vendor snapshot. Such modules must create both cfi and non-cfi variants,
// except for ones which explicitly disable cfi.
func needsCfiForVendorSnapshot(mctx android.TopDownMutatorContext) bool {
if isVendorProprietaryPath(mctx.ModuleDir()) {
return false
}
c := mctx.Module().(*Module)
if !c.inVendor() {
return false
}
if !c.static() {
return false
}
if c.Prebuilt() != nil {
return false
}
return c.sanitize != nil &&
!Bool(c.sanitize.Properties.Sanitize.Never) &&
!c.sanitize.isSanitizerExplicitlyDisabled(cfi)
}
// Propagate sanitizer requirements down from binaries // Propagate sanitizer requirements down from binaries
func sanitizerDepsMutator(t sanitizerType) func(android.TopDownMutatorContext) { func sanitizerDepsMutator(t sanitizerType) func(android.TopDownMutatorContext) {
return func(mctx android.TopDownMutatorContext) { return func(mctx android.TopDownMutatorContext) {
if c, ok := mctx.Module().(*Module); ok && c.sanitize.isSanitizerEnabled(t) { if c, ok := mctx.Module().(*Module); ok {
mctx.WalkDeps(func(child, parent android.Module) bool { enabled := c.sanitize.isSanitizerEnabled(t)
if !isSanitizableDependencyTag(mctx.OtherModuleDependencyTag(child)) { if t == cfi && needsCfiForVendorSnapshot(mctx) {
return false // We shouldn't change the result of isSanitizerEnabled(cfi) to correctly
} // determine defaultVariation in sanitizerMutator below.
if d, ok := child.(*Module); ok && d.sanitize != nil && // Instead, just mark SanitizeDep to forcefully create cfi variant.
!Bool(d.sanitize.Properties.Sanitize.Never) && enabled = true
!d.sanitize.isSanitizerExplicitlyDisabled(t) { c.sanitize.Properties.SanitizeDep = true
if t == cfi || t == hwasan || t == scs { }
if d.static() { if enabled {
mctx.WalkDeps(func(child, parent android.Module) bool {
if !isSanitizableDependencyTag(mctx.OtherModuleDependencyTag(child)) {
return false
}
if d, ok := child.(*Module); ok && d.sanitize != nil &&
!Bool(d.sanitize.Properties.Sanitize.Never) &&
!d.sanitize.isSanitizerExplicitlyDisabled(t) {
if t == cfi || t == hwasan || t == scs {
if d.static() {
d.sanitize.Properties.SanitizeDep = true
}
} else {
d.sanitize.Properties.SanitizeDep = true d.sanitize.Properties.SanitizeDep = true
} }
} else {
d.sanitize.Properties.SanitizeDep = true
} }
} return true
return true })
}) }
} else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok { } else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok {
// If an APEX module includes a lib which is enabled for a sanitizer T, then // If an APEX module includes a lib which is enabled for a sanitizer T, then
// the APEX module is also enabled for the same sanitizer type. // the APEX module is also enabled for the same sanitizer type.
@@ -1095,6 +1133,24 @@ func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
// APEX modules fall here // APEX modules fall here
sanitizeable.AddSanitizerDependencies(mctx, t.name()) sanitizeable.AddSanitizerDependencies(mctx, t.name())
mctx.CreateVariations(t.variationName()) mctx.CreateVariations(t.variationName())
} else if c, ok := mctx.Module().(*Module); ok {
// Check if it's a snapshot module supporting sanitizer
if s, ok := c.linker.(snapshotSanitizer); ok && s.isSanitizerEnabled(t) {
// Set default variation as above.
defaultVariation := t.variationName()
mctx.SetDefaultDependencyVariation(&defaultVariation)
modules := mctx.CreateVariations("", t.variationName())
modules[0].(*Module).linker.(snapshotSanitizer).setSanitizerVariation(t, false)
modules[1].(*Module).linker.(snapshotSanitizer).setSanitizerVariation(t, true)
// Export the static lib name to make
if c.static() && c.ExportedToMake() {
if t == cfi {
// use BaseModuleName which is the name for Make.
cfiStaticLibs(mctx.Config()).add(c, c.BaseModuleName())
}
}
}
} }
} }
} }

View File

@@ -567,6 +567,7 @@ func CreateTestContext() *android.TestContext {
ctx.RegisterModuleType("filegroup", android.FileGroupFactory) ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
ctx.RegisterModuleType("vndk_libraries_txt", VndkLibrariesTxtFactory) ctx.RegisterModuleType("vndk_libraries_txt", VndkLibrariesTxtFactory)
ctx.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
android.RegisterPrebuiltMutators(ctx) android.RegisterPrebuiltMutators(ctx)
RegisterRequiredBuildComponentsForTest(ctx) RegisterRequiredBuildComponentsForTest(ctx)

View File

@@ -80,23 +80,75 @@ func vendorSnapshotObjects(config android.Config) *snapshotMap {
}).(*snapshotMap) }).(*snapshotMap)
} }
type vendorSnapshotLibraryProperties struct { type vendorSnapshotBaseProperties struct {
// snapshot version. // snapshot version.
Version string Version string
// Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64') // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64')
Target_arch string Target_arch string
}
// vendorSnapshotModuleBase provides common basic functions for all snapshot modules.
type vendorSnapshotModuleBase struct {
baseProperties vendorSnapshotBaseProperties
moduleSuffix string
}
func (p *vendorSnapshotModuleBase) Name(name string) string {
return name + p.NameSuffix()
}
func (p *vendorSnapshotModuleBase) NameSuffix() string {
versionSuffix := p.version()
if p.arch() != "" {
versionSuffix += "." + p.arch()
}
return p.moduleSuffix + versionSuffix
}
func (p *vendorSnapshotModuleBase) version() string {
return p.baseProperties.Version
}
func (p *vendorSnapshotModuleBase) arch() string {
return p.baseProperties.Target_arch
}
func (p *vendorSnapshotModuleBase) isSnapshotPrebuilt() bool {
return true
}
// Call this after creating a snapshot module with module suffix
// such as vendorSnapshotSharedSuffix
func (p *vendorSnapshotModuleBase) init(m *Module, suffix string) {
p.moduleSuffix = suffix
m.AddProperties(&p.baseProperties)
android.AddLoadHook(m, func(ctx android.LoadHookContext) {
vendorSnapshotLoadHook(ctx, p)
})
}
func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *vendorSnapshotModuleBase) {
if p.version() != ctx.DeviceConfig().VndkVersion() {
ctx.Module().Disable()
return
}
}
type vendorSnapshotLibraryProperties struct {
// Prebuilt file for each arch. // Prebuilt file for each arch.
Src *string `android:"arch_variant"` Src *string `android:"arch_variant"`
// list of directories that will be added to the include path (using -I).
Export_include_dirs []string `android:"arch_variant"`
// list of directories that will be added to the system path (using -isystem).
Export_system_include_dirs []string `android:"arch_variant"`
// list of flags that will be used for any module that links against this module. // list of flags that will be used for any module that links against this module.
Export_flags []string `android:"arch_variant"` Export_flags []string `android:"arch_variant"`
// Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols,
// etc).
Check_elf_files *bool
// Whether this prebuilt needs to depend on sanitize ubsan runtime or not. // Whether this prebuilt needs to depend on sanitize ubsan runtime or not.
Sanitize_ubsan_dep *bool `android:"arch_variant"` Sanitize_ubsan_dep *bool `android:"arch_variant"`
@@ -104,42 +156,24 @@ type vendorSnapshotLibraryProperties struct {
Sanitize_minimal_dep *bool `android:"arch_variant"` Sanitize_minimal_dep *bool `android:"arch_variant"`
} }
type snapshotSanitizer interface {
isSanitizerEnabled(t sanitizerType) bool
setSanitizerVariation(t sanitizerType, enabled bool)
}
type vendorSnapshotLibraryDecorator struct { type vendorSnapshotLibraryDecorator struct {
vendorSnapshotModuleBase
*libraryDecorator *libraryDecorator
properties vendorSnapshotLibraryProperties properties vendorSnapshotLibraryProperties
sanitizerProperties struct {
CfiEnabled bool `blueprint:"mutated"`
// Library flags for cfi variant.
Cfi vendorSnapshotLibraryProperties `android:"arch_variant"`
}
androidMkVendorSuffix bool androidMkVendorSuffix bool
} }
func (p *vendorSnapshotLibraryDecorator) Name(name string) string {
return name + p.NameSuffix()
}
func (p *vendorSnapshotLibraryDecorator) NameSuffix() string {
versionSuffix := p.version()
if p.arch() != "" {
versionSuffix += "." + p.arch()
}
var linkageSuffix string
if p.buildShared() {
linkageSuffix = vendorSnapshotSharedSuffix
} else if p.buildStatic() {
linkageSuffix = vendorSnapshotStaticSuffix
} else {
linkageSuffix = vendorSnapshotHeaderSuffix
}
return linkageSuffix + versionSuffix
}
func (p *vendorSnapshotLibraryDecorator) version() string {
return p.properties.Version
}
func (p *vendorSnapshotLibraryDecorator) arch() string {
return p.properties.Target_arch
}
func (p *vendorSnapshotLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { func (p *vendorSnapshotLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix()) p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix())
return p.libraryDecorator.linkerFlags(ctx, flags) return p.libraryDecorator.linkerFlags(ctx, flags)
@@ -165,11 +199,16 @@ func (p *vendorSnapshotLibraryDecorator) link(ctx ModuleContext,
return p.libraryDecorator.link(ctx, flags, deps, objs) return p.libraryDecorator.link(ctx, flags, deps, objs)
} }
if p.sanitizerProperties.CfiEnabled {
p.properties = p.sanitizerProperties.Cfi
}
if !p.matchesWithDevice(ctx.DeviceConfig()) { if !p.matchesWithDevice(ctx.DeviceConfig()) {
return nil return nil
} }
p.libraryDecorator.exportIncludes(ctx) p.libraryDecorator.reexportDirs(android.PathsForModuleSrc(ctx, p.properties.Export_include_dirs)...)
p.libraryDecorator.reexportSystemDirs(android.PathsForModuleSrc(ctx, p.properties.Export_system_include_dirs)...)
p.libraryDecorator.reexportFlags(p.properties.Export_flags...) p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
in := android.PathForModuleSrc(ctx, *p.properties.Src) in := android.PathForModuleSrc(ctx, *p.properties.Src)
@@ -189,32 +228,38 @@ func (p *vendorSnapshotLibraryDecorator) link(ctx ModuleContext,
return in return in
} }
func (p *vendorSnapshotLibraryDecorator) nativeCoverage() bool {
return false
}
func (p *vendorSnapshotLibraryDecorator) isSnapshotPrebuilt() bool {
return true
}
func (p *vendorSnapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) { func (p *vendorSnapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) {
if p.matchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) { if p.matchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) {
p.baseInstaller.install(ctx, file) p.baseInstaller.install(ctx, file)
} }
} }
type vendorSnapshotInterface interface { func (p *vendorSnapshotLibraryDecorator) nativeCoverage() bool {
version() string return false
} }
func vendorSnapshotLoadHook(ctx android.LoadHookContext, p vendorSnapshotInterface) { func (p *vendorSnapshotLibraryDecorator) isSanitizerEnabled(t sanitizerType) bool {
if p.version() != ctx.DeviceConfig().VndkVersion() { switch t {
ctx.Module().Disable() case cfi:
return p.sanitizerProperties.Cfi.Src != nil
default:
return false
}
}
func (p *vendorSnapshotLibraryDecorator) setSanitizerVariation(t sanitizerType, enabled bool) {
if !enabled {
return
}
switch t {
case cfi:
p.sanitizerProperties.CfiEnabled = true
default:
return return
} }
} }
func vendorSnapshotLibrary() (*Module, *vendorSnapshotLibraryDecorator) { func vendorSnapshotLibrary(suffix string) (*Module, *vendorSnapshotLibraryDecorator) {
module, library := NewLibrary(android.DeviceSupported) module, library := NewLibrary(android.DeviceSupported)
module.stl = nil module.stl = nil
@@ -237,77 +282,47 @@ func vendorSnapshotLibrary() (*Module, *vendorSnapshotLibraryDecorator) {
module.linker = prebuilt module.linker = prebuilt
module.installer = prebuilt module.installer = prebuilt
prebuilt.init(module, suffix)
module.AddProperties( module.AddProperties(
&prebuilt.properties, &prebuilt.properties,
&prebuilt.sanitizerProperties,
) )
return module, prebuilt return module, prebuilt
} }
func VendorSnapshotSharedFactory() android.Module { func VendorSnapshotSharedFactory() android.Module {
module, prebuilt := vendorSnapshotLibrary() module, prebuilt := vendorSnapshotLibrary(vendorSnapshotSharedSuffix)
prebuilt.libraryDecorator.BuildOnlyShared() prebuilt.libraryDecorator.BuildOnlyShared()
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
vendorSnapshotLoadHook(ctx, prebuilt)
})
return module.Init() return module.Init()
} }
func VendorSnapshotStaticFactory() android.Module { func VendorSnapshotStaticFactory() android.Module {
module, prebuilt := vendorSnapshotLibrary() module, prebuilt := vendorSnapshotLibrary(vendorSnapshotStaticSuffix)
prebuilt.libraryDecorator.BuildOnlyStatic() prebuilt.libraryDecorator.BuildOnlyStatic()
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
vendorSnapshotLoadHook(ctx, prebuilt)
})
return module.Init() return module.Init()
} }
func VendorSnapshotHeaderFactory() android.Module { func VendorSnapshotHeaderFactory() android.Module {
module, prebuilt := vendorSnapshotLibrary() module, prebuilt := vendorSnapshotLibrary(vendorSnapshotHeaderSuffix)
prebuilt.libraryDecorator.HeaderOnly() prebuilt.libraryDecorator.HeaderOnly()
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
vendorSnapshotLoadHook(ctx, prebuilt)
})
return module.Init() return module.Init()
} }
var _ snapshotSanitizer = (*vendorSnapshotLibraryDecorator)(nil)
type vendorSnapshotBinaryProperties struct { type vendorSnapshotBinaryProperties struct {
// snapshot version.
Version string
// Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64_ab')
Target_arch string
// Prebuilt file for each arch. // Prebuilt file for each arch.
Src *string `android:"arch_variant"` Src *string `android:"arch_variant"`
} }
type vendorSnapshotBinaryDecorator struct { type vendorSnapshotBinaryDecorator struct {
vendorSnapshotModuleBase
*binaryDecorator *binaryDecorator
properties vendorSnapshotBinaryProperties properties vendorSnapshotBinaryProperties
androidMkVendorSuffix bool androidMkVendorSuffix bool
} }
func (p *vendorSnapshotBinaryDecorator) Name(name string) string {
return name + p.NameSuffix()
}
func (p *vendorSnapshotBinaryDecorator) NameSuffix() string {
versionSuffix := p.version()
if p.arch() != "" {
versionSuffix += "." + p.arch()
}
return vendorSnapshotBinarySuffix + versionSuffix
}
func (p *vendorSnapshotBinaryDecorator) version() string {
return p.properties.Version
}
func (p *vendorSnapshotBinaryDecorator) arch() string {
return p.properties.Target_arch
}
func (p *vendorSnapshotBinaryDecorator) matchesWithDevice(config android.DeviceConfig) bool { func (p *vendorSnapshotBinaryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
if config.DeviceArch() != p.arch() { if config.DeviceArch() != p.arch() {
return false return false
@@ -349,8 +364,8 @@ func (p *vendorSnapshotBinaryDecorator) link(ctx ModuleContext,
return outputFile return outputFile
} }
func (p *vendorSnapshotBinaryDecorator) isSnapshotPrebuilt() bool { func (p *vendorSnapshotBinaryDecorator) nativeCoverage() bool {
return true return false
} }
func VendorSnapshotBinaryFactory() android.Module { func VendorSnapshotBinaryFactory() android.Module {
@@ -372,51 +387,23 @@ func VendorSnapshotBinaryFactory() android.Module {
module.stl = nil module.stl = nil
module.linker = prebuilt module.linker = prebuilt
android.AddLoadHook(module, func(ctx android.LoadHookContext) { prebuilt.init(module, vendorSnapshotBinarySuffix)
vendorSnapshotLoadHook(ctx, prebuilt)
})
module.AddProperties(&prebuilt.properties) module.AddProperties(&prebuilt.properties)
return module.Init() return module.Init()
} }
type vendorSnapshotObjectProperties struct { type vendorSnapshotObjectProperties struct {
// snapshot version.
Version string
// Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64_ab')
Target_arch string
// Prebuilt file for each arch. // Prebuilt file for each arch.
Src *string `android:"arch_variant"` Src *string `android:"arch_variant"`
} }
type vendorSnapshotObjectLinker struct { type vendorSnapshotObjectLinker struct {
vendorSnapshotModuleBase
objectLinker objectLinker
properties vendorSnapshotObjectProperties properties vendorSnapshotObjectProperties
androidMkVendorSuffix bool androidMkVendorSuffix bool
} }
func (p *vendorSnapshotObjectLinker) Name(name string) string {
return name + p.NameSuffix()
}
func (p *vendorSnapshotObjectLinker) NameSuffix() string {
versionSuffix := p.version()
if p.arch() != "" {
versionSuffix += "." + p.arch()
}
return vendorSnapshotObjectSuffix + versionSuffix
}
func (p *vendorSnapshotObjectLinker) version() string {
return p.properties.Version
}
func (p *vendorSnapshotObjectLinker) arch() string {
return p.properties.Target_arch
}
func (p *vendorSnapshotObjectLinker) matchesWithDevice(config android.DeviceConfig) bool { func (p *vendorSnapshotObjectLinker) matchesWithDevice(config android.DeviceConfig) bool {
if config.DeviceArch() != p.arch() { if config.DeviceArch() != p.arch() {
return false return false
@@ -443,10 +430,6 @@ func (p *vendorSnapshotObjectLinker) nativeCoverage() bool {
return false return false
} }
func (p *vendorSnapshotObjectLinker) isSnapshotPrebuilt() bool {
return true
}
func VendorSnapshotObjectFactory() android.Module { func VendorSnapshotObjectFactory() android.Module {
module := newObject() module := newObject()
@@ -457,10 +440,7 @@ func VendorSnapshotObjectFactory() android.Module {
} }
module.linker = prebuilt module.linker = prebuilt
android.AddLoadHook(module, func(ctx android.LoadHookContext) { prebuilt.init(module, vendorSnapshotObjectSuffix)
vendorSnapshotLoadHook(ctx, prebuilt)
})
module.AddProperties(&prebuilt.properties) module.AddProperties(&prebuilt.properties)
return module.Init() return module.Init()
} }
@@ -568,13 +548,17 @@ func isVendorSnapshotModule(m *Module, moduleDir string) bool {
if l, ok := m.linker.(snapshotLibraryInterface); ok { if l, ok := m.linker.(snapshotLibraryInterface); ok {
// TODO(b/65377115): add full support for sanitizer // TODO(b/65377115): add full support for sanitizer
if m.sanitize != nil { if m.sanitize != nil {
// cfi, scs and hwasan export both sanitized and unsanitized variants for static and header // scs and hwasan export both sanitized and unsanitized variants for static and header
// Always use unsanitized variants of them. // Always use unsanitized variants of them.
for _, t := range []sanitizerType{cfi, scs, hwasan} { for _, t := range []sanitizerType{scs, hwasan} {
if !l.shared() && m.sanitize.isSanitizerEnabled(t) { if !l.shared() && m.sanitize.isSanitizerEnabled(t) {
return false return false
} }
} }
// cfi also exports both variants. But for static, we capture both.
if !l.static() && !l.shared() && m.sanitize.isSanitizerEnabled(cfi) {
return false
}
} }
if l.static() { if l.static() {
return m.outputFile.Valid() && proptools.BoolDefault(m.VendorProperties.Vendor_available, true) return m.outputFile.Valid() && proptools.BoolDefault(m.VendorProperties.Vendor_available, true)
@@ -668,6 +652,7 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont
ExportedDirs []string `json:",omitempty"` ExportedDirs []string `json:",omitempty"`
ExportedSystemDirs []string `json:",omitempty"` ExportedSystemDirs []string `json:",omitempty"`
ExportedFlags []string `json:",omitempty"` ExportedFlags []string `json:",omitempty"`
Sanitize string `json:",omitempty"`
SanitizeMinimalDep bool `json:",omitempty"` SanitizeMinimalDep bool `json:",omitempty"`
SanitizeUbsanDep bool `json:",omitempty"` SanitizeUbsanDep bool `json:",omitempty"`
@@ -717,6 +702,7 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont
var propOut string var propOut string
if l, ok := m.linker.(snapshotLibraryInterface); ok { if l, ok := m.linker.(snapshotLibraryInterface); ok {
// library flags // library flags
prop.ExportedFlags = l.exportedFlags() prop.ExportedFlags = l.exportedFlags()
for _, dir := range l.exportedDirs() { for _, dir := range l.exportedDirs() {
@@ -749,6 +735,15 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont
if libType != "header" { if libType != "header" {
libPath := m.outputFile.Path() libPath := m.outputFile.Path()
stem = libPath.Base() stem = libPath.Base()
if l.static() && m.sanitize != nil && m.sanitize.isSanitizerEnabled(cfi) {
// both cfi and non-cfi variant for static libraries can exist.
// attach .cfi to distinguish between cfi and non-cfi.
// e.g. libbase.a -> libbase.cfi.a
ext := filepath.Ext(stem)
stem = strings.TrimSuffix(stem, ext) + ".cfi" + ext
prop.Sanitize = "cfi"
prop.ModuleName += ".cfi"
}
snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem) snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
ret = append(ret, copyFile(ctx, libPath, snapshotLibOut)) ret = append(ret, copyFile(ctx, libPath, snapshotLibOut))
} else { } else {