Merge "Support asan/hwasan versions of prebuilts." am: 00e07c9779 am: 2cd36f0b0a am: 77436ca9fe

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1371811

Change-Id: I409f6db3d48cf4aff49c5eb9291d99578a2e02f6
This commit is contained in:
Evgenii Stepanov
2020-10-13 19:01:17 +00:00
committed by Automerger Merge Worker
6 changed files with 205 additions and 17 deletions

View File

@@ -93,7 +93,7 @@ func (p *Prebuilt) Prefer() bool {
// more modules like this. // more modules like this.
func (p *Prebuilt) SingleSourcePath(ctx ModuleContext) Path { func (p *Prebuilt) SingleSourcePath(ctx ModuleContext) Path {
if p.srcsSupplier != nil { if p.srcsSupplier != nil {
srcs := p.srcsSupplier() srcs := p.srcsSupplier(ctx)
if len(srcs) == 0 { if len(srcs) == 0 {
ctx.PropertyErrorf(p.srcsPropertyName, "missing prebuilt source file") ctx.PropertyErrorf(p.srcsPropertyName, "missing prebuilt source file")
@@ -122,7 +122,7 @@ func (p *Prebuilt) UsePrebuilt() bool {
// Called to provide the srcs value for the prebuilt module. // Called to provide the srcs value for the prebuilt module.
// //
// Return the src value or nil if it is not available. // Return the src value or nil if it is not available.
type PrebuiltSrcsSupplier func() []string type PrebuiltSrcsSupplier func(ctx BaseModuleContext) []string
// Initialize the module as a prebuilt module that uses the provided supplier to access the // Initialize the module as a prebuilt module that uses the provided supplier to access the
// prebuilt sources of the module. // prebuilt sources of the module.
@@ -156,7 +156,7 @@ func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) {
panic(fmt.Errorf("srcs must not be nil")) panic(fmt.Errorf("srcs must not be nil"))
} }
srcsSupplier := func() []string { srcsSupplier := func(ctx BaseModuleContext) []string {
return *srcs return *srcs
} }
@@ -177,7 +177,7 @@ func InitSingleSourcePrebuiltModule(module PrebuiltInterface, srcProps interface
srcFieldIndex := srcStructField.Index srcFieldIndex := srcStructField.Index
srcPropertyName := proptools.PropertyNameForField(srcField) srcPropertyName := proptools.PropertyNameForField(srcField)
srcsSupplier := func() []string { srcsSupplier := func(ctx BaseModuleContext) []string {
value := srcPropsValue.FieldByIndex(srcFieldIndex) value := srcPropsValue.FieldByIndex(srcFieldIndex)
if value.Kind() == reflect.Ptr { if value.Kind() == reflect.Ptr {
value = value.Elem() value = value.Elem()
@@ -287,7 +287,7 @@ func PrebuiltPostDepsMutator(ctx BottomUpMutatorContext) {
// usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt // usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt
// will be used if it is marked "prefer" or if the source module is disabled. // will be used if it is marked "prefer" or if the source module is disabled.
func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module) bool { func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module) bool {
if p.srcsSupplier != nil && len(p.srcsSupplier()) == 0 { if p.srcsSupplier != nil && len(p.srcsSupplier(ctx)) == 0 {
return false return false
} }

View File

@@ -5597,6 +5597,36 @@ func TestAppSetBundle(t *testing.T) {
ensureMatches(t, copyCmds[2], "^unzip .*-d .*/app/AppSet .*/AppSet.zip$") ensureMatches(t, copyCmds[2], "^unzip .*-d .*/app/AppSet .*/AppSet.zip$")
} }
func TestAppSetBundlePrebuilt(t *testing.T) {
ctx, _ := testApex(t, "", func(fs map[string][]byte, config android.Config) {
bp := `
apex_set {
name: "myapex",
filename: "foo_v2.apex",
sanitized: {
none: { set: "myapex.apks", },
hwaddress: { set: "myapex.hwasan.apks", },
},
}`
fs["Android.bp"] = []byte(bp)
config.TestProductVariables.SanitizeDevice = []string{"hwaddress"}
})
m := ctx.ModuleForTests("myapex", "android_common")
extractedApex := m.Output(buildDir + "/.intermediates/myapex/android_common/foo_v2.apex")
actual := extractedApex.Inputs
if len(actual) != 1 {
t.Errorf("expected a single input")
}
expected := "myapex.hwasan.apks"
if actual[0].String() != expected {
t.Errorf("expected %s, got %s", expected, actual[0].String())
}
}
func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) { func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) {
t.Helper() t.Helper()

View File

@@ -50,6 +50,10 @@ type prebuiltCommon struct {
properties prebuiltCommonProperties properties prebuiltCommonProperties
} }
type sanitizedPrebuilt interface {
hasSanitizedSource(sanitizer string) bool
}
type prebuiltCommonProperties struct { type prebuiltCommonProperties struct {
ForceDisable bool `blueprint:"mutated"` ForceDisable bool `blueprint:"mutated"`
} }
@@ -75,9 +79,10 @@ func (p *prebuiltCommon) checkForceDisable(ctx android.ModuleContext) bool {
forceDisable = forceDisable || ctx.DeviceConfig().NativeCoverageEnabled() forceDisable = forceDisable || ctx.DeviceConfig().NativeCoverageEnabled()
forceDisable = forceDisable || ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") forceDisable = forceDisable || ctx.Config().IsEnvTrue("EMMA_INSTRUMENT")
// b/137216042 don't use prebuilts when address sanitizer is on // b/137216042 don't use prebuilts when address sanitizer is on, unless the prebuilt has a sanitized source
forceDisable = forceDisable || android.InList("address", ctx.Config().SanitizeDevice()) || sanitized := ctx.Module().(sanitizedPrebuilt)
android.InList("hwaddress", ctx.Config().SanitizeDevice()) forceDisable = forceDisable || (android.InList("address", ctx.Config().SanitizeDevice()) && !sanitized.hasSanitizedSource("address"))
forceDisable = forceDisable || (android.InList("hwaddress", ctx.Config().SanitizeDevice()) && !sanitized.hasSanitizedSource("hwaddress"))
if forceDisable && p.prebuilt.SourceExists() { if forceDisable && p.prebuilt.SourceExists() {
p.properties.ForceDisable = true p.properties.ForceDisable = true
@@ -135,6 +140,10 @@ type PrebuiltProperties struct {
Overrides []string Overrides []string
} }
func (a *Prebuilt) hasSanitizedSource(sanitizer string) bool {
return false
}
func (p *Prebuilt) installable() bool { func (p *Prebuilt) installable() bool {
return p.properties.Installable == nil || proptools.Bool(p.properties.Installable) return p.properties.Installable == nil || proptools.Bool(p.properties.Installable)
} }
@@ -266,6 +275,18 @@ type ApexSetProperties struct {
// the .apks file path that contains prebuilt apex files to be extracted. // the .apks file path that contains prebuilt apex files to be extracted.
Set *string Set *string
Sanitized struct {
None struct {
Set *string
}
Address struct {
Set *string
}
Hwaddress struct {
Set *string
}
}
// whether the extracted apex file installable. // whether the extracted apex file installable.
Installable *bool Installable *bool
@@ -284,6 +305,41 @@ type ApexSetProperties struct {
Prerelease *bool Prerelease *bool
} }
func (a *ApexSet) prebuiltSrcs(ctx android.BaseModuleContext) []string {
var srcs []string
if a.properties.Set != nil {
srcs = append(srcs, *a.properties.Set)
}
var sanitizers []string
if ctx.Host() {
sanitizers = ctx.Config().SanitizeHost()
} else {
sanitizers = ctx.Config().SanitizeDevice()
}
if android.InList("address", sanitizers) && a.properties.Sanitized.Address.Set != nil {
srcs = append(srcs, *a.properties.Sanitized.Address.Set)
} else if android.InList("hwaddress", sanitizers) && a.properties.Sanitized.Hwaddress.Set != nil {
srcs = append(srcs, *a.properties.Sanitized.Hwaddress.Set)
} else if a.properties.Sanitized.None.Set != nil {
srcs = append(srcs, *a.properties.Sanitized.None.Set)
}
return srcs
}
func (a *ApexSet) hasSanitizedSource(sanitizer string) bool {
if sanitizer == "address" {
return a.properties.Sanitized.Address.Set != nil
}
if sanitizer == "hwaddress" {
return a.properties.Sanitized.Hwaddress.Set != nil
}
return false
}
func (a *ApexSet) installable() bool { func (a *ApexSet) installable() bool {
return a.properties.Installable == nil || proptools.Bool(a.properties.Installable) return a.properties.Installable == nil || proptools.Bool(a.properties.Installable)
} }
@@ -304,7 +360,12 @@ func (a *ApexSet) Overrides() []string {
func apexSetFactory() android.Module { func apexSetFactory() android.Module {
module := &ApexSet{} module := &ApexSet{}
module.AddProperties(&module.properties) module.AddProperties(&module.properties)
android.InitSingleSourcePrebuiltModule(module, &module.properties, "Set")
srcsSupplier := func(ctx android.BaseModuleContext) []string {
return module.prebuiltSrcs(ctx)
}
android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "set")
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
return module return module
} }

View File

@@ -121,7 +121,10 @@ type SharedProperties struct {
} }
type StaticOrSharedProperties struct { type StaticOrSharedProperties struct {
Srcs []string `android:"path,arch_variant"` Srcs []string `android:"path,arch_variant"`
Sanitized Sanitized `android:"arch_variant"`
Cflags []string `android:"arch_variant"` Cflags []string `android:"arch_variant"`
Enabled *bool `android:"arch_variant"` Enabled *bool `android:"arch_variant"`

View File

@@ -38,10 +38,11 @@ type prebuiltLinkerInterface interface {
} }
type prebuiltLinkerProperties struct { type prebuiltLinkerProperties struct {
// a prebuilt library or binary. Can reference a genrule module that generates an executable file. // a prebuilt library or binary. Can reference a genrule module that generates an executable file.
Srcs []string `android:"path,arch_variant"` Srcs []string `android:"path,arch_variant"`
Sanitized Sanitized `android:"arch_variant"`
// Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined // Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined
// symbols, etc), default true. // symbols, etc), default true.
Check_elf_files *bool Check_elf_files *bool
@@ -105,7 +106,7 @@ func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...) p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
// TODO(ccross): verify shared library dependencies // TODO(ccross): verify shared library dependencies
srcs := p.prebuiltSrcs() srcs := p.prebuiltSrcs(ctx)
if len(srcs) > 0 { if len(srcs) > 0 {
builderFlags := flagsToBuilderFlags(flags) builderFlags := flagsToBuilderFlags(flags)
@@ -177,15 +178,18 @@ func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
return nil return nil
} }
func (p *prebuiltLibraryLinker) prebuiltSrcs() []string { func (p *prebuiltLibraryLinker) prebuiltSrcs(ctx android.BaseModuleContext) []string {
sanitize := ctx.Module().(*Module).sanitize
srcs := p.properties.Srcs srcs := p.properties.Srcs
srcs = append(srcs, srcsForSanitizer(sanitize, p.properties.Sanitized)...)
if p.static() { if p.static() {
srcs = append(srcs, p.libraryDecorator.StaticProperties.Static.Srcs...) srcs = append(srcs, p.libraryDecorator.StaticProperties.Static.Srcs...)
srcs = append(srcs, srcsForSanitizer(sanitize, p.libraryDecorator.StaticProperties.Static.Sanitized)...)
} }
if p.shared() { if p.shared() {
srcs = append(srcs, p.libraryDecorator.SharedProperties.Shared.Srcs...) srcs = append(srcs, p.libraryDecorator.SharedProperties.Shared.Srcs...)
srcs = append(srcs, srcsForSanitizer(sanitize, p.libraryDecorator.SharedProperties.Shared.Sanitized)...)
} }
return srcs return srcs
} }
@@ -212,8 +216,8 @@ func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDec
module.AddProperties(&prebuilt.properties) module.AddProperties(&prebuilt.properties)
srcsSupplier := func() []string { srcsSupplier := func(ctx android.BaseModuleContext) []string {
return prebuilt.prebuiltSrcs() return prebuilt.prebuiltSrcs(ctx)
} }
android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "srcs") android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "srcs")
@@ -425,3 +429,28 @@ func NewPrebuiltBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecor
android.InitPrebuiltModule(module, &prebuilt.properties.Srcs) android.InitPrebuiltModule(module, &prebuilt.properties.Srcs)
return module, binary return module, binary
} }
type Sanitized struct {
None struct {
Srcs []string `android:"path,arch_variant"`
} `android:"arch_variant"`
Address struct {
Srcs []string `android:"path,arch_variant"`
} `android:"arch_variant"`
Hwaddress struct {
Srcs []string `android:"path,arch_variant"`
} `android:"arch_variant"`
}
func srcsForSanitizer(sanitize *sanitize, sanitized Sanitized) []string {
if sanitize == nil {
return nil
}
if Bool(sanitize.Properties.Sanitize.Address) && sanitized.Address.Srcs != nil {
return sanitized.Address.Srcs
}
if Bool(sanitize.Properties.Sanitize.Hwaddress) && sanitized.Hwaddress.Srcs != nil {
return sanitized.Hwaddress.Srcs
}
return sanitized.None.Srcs
}

View File

@@ -23,7 +23,7 @@ import (
"github.com/google/blueprint" "github.com/google/blueprint"
) )
func testPrebuilt(t *testing.T, bp string, fs map[string][]byte) *android.TestContext { func testPrebuilt(t *testing.T, bp string, fs map[string][]byte, handlers ...configCustomizer) *android.TestContext {
config := TestConfig(buildDir, android.Android, nil, bp, fs) config := TestConfig(buildDir, android.Android, nil, bp, fs)
ctx := CreateTestContext() ctx := CreateTestContext()
@@ -34,6 +34,10 @@ func testPrebuilt(t *testing.T, bp string, fs map[string][]byte) *android.TestCo
android.RegisterAndroidMkBuildComponents(ctx) android.RegisterAndroidMkBuildComponents(ctx)
android.SetInMakeForTests(config) android.SetInMakeForTests(config)
for _, handler := range handlers {
handler(config)
}
ctx.Register(config) ctx.Register(config)
_, errs := ctx.ParseFileList(".", []string{"Android.bp"}) _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
android.FailIfErrored(t, errs) android.FailIfErrored(t, errs)
@@ -42,6 +46,8 @@ func testPrebuilt(t *testing.T, bp string, fs map[string][]byte) *android.TestCo
return ctx return ctx
} }
type configCustomizer func(config android.Config)
func TestPrebuilt(t *testing.T) { func TestPrebuilt(t *testing.T) {
bp := ` bp := `
cc_library { cc_library {
@@ -321,3 +327,62 @@ func TestPrebuiltSymlinkedHostBinary(t *testing.T) {
assertString(t, libfooDep.String(), assertString(t, libfooDep.String(),
filepath.Join(buildDir, ".intermediates/libfoo/linux_glibc_x86_64_shared/libfoo.so")) filepath.Join(buildDir, ".intermediates/libfoo/linux_glibc_x86_64_shared/libfoo.so"))
} }
func TestPrebuiltLibrarySanitized(t *testing.T) {
bp := `cc_prebuilt_library {
name: "libtest",
static: {
sanitized: { none: { srcs: ["libf.a"], }, hwaddress: { srcs: ["libf.hwasan.a"], }, },
},
shared: {
sanitized: { none: { srcs: ["libf.so"], }, hwaddress: { srcs: ["hwasan/libf.so"], }, },
},
}
cc_prebuilt_library_static {
name: "libtest_static",
sanitized: { none: { srcs: ["libf.a"], }, hwaddress: { srcs: ["libf.hwasan.a"], }, },
}
cc_prebuilt_library_shared {
name: "libtest_shared",
sanitized: { none: { srcs: ["libf.so"], }, hwaddress: { srcs: ["hwasan/libf.so"], }, },
}`
fs := map[string][]byte{
"libf.a": nil,
"libf.hwasan.a": nil,
"libf.so": nil,
"hwasan/libf.so": nil,
}
// Without SANITIZE_TARGET.
ctx := testPrebuilt(t, bp, fs)
shared_rule := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip")
assertString(t, shared_rule.Input.String(), "libf.so")
static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module)
assertString(t, static.OutputFile().Path().Base(), "libf.a")
shared_rule2 := ctx.ModuleForTests("libtest_shared", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip")
assertString(t, shared_rule2.Input.String(), "libf.so")
static2 := ctx.ModuleForTests("libtest_static", "android_arm64_armv8-a_static").Module().(*Module)
assertString(t, static2.OutputFile().Path().Base(), "libf.a")
// With SANITIZE_TARGET=hwaddress
ctx = testPrebuilt(t, bp, fs, func(config android.Config) {
config.TestProductVariables.SanitizeDevice = []string{"hwaddress"}
})
shared_rule = ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip")
assertString(t, shared_rule.Input.String(), "hwasan/libf.so")
static = ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static_hwasan").Module().(*Module)
assertString(t, static.OutputFile().Path().Base(), "libf.hwasan.a")
shared_rule2 = ctx.ModuleForTests("libtest_shared", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip")
assertString(t, shared_rule2.Input.String(), "hwasan/libf.so")
static2 = ctx.ModuleForTests("libtest_static", "android_arm64_armv8-a_static_hwasan").Module().(*Module)
assertString(t, static2.OutputFile().Path().Base(), "libf.hwasan.a")
}