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
commit 4fd6798169
6 changed files with 205 additions and 17 deletions

View file

@ -93,7 +93,7 @@ func (p *Prebuilt) Prefer() bool {
// more modules like this.
func (p *Prebuilt) SingleSourcePath(ctx ModuleContext) Path {
if p.srcsSupplier != nil {
srcs := p.srcsSupplier()
srcs := p.srcsSupplier(ctx)
if len(srcs) == 0 {
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.
//
// 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
// prebuilt sources of the module.
@ -156,7 +156,7 @@ func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) {
panic(fmt.Errorf("srcs must not be nil"))
}
srcsSupplier := func() []string {
srcsSupplier := func(ctx BaseModuleContext) []string {
return *srcs
}
@ -177,7 +177,7 @@ func InitSingleSourcePrebuiltModule(module PrebuiltInterface, srcProps interface
srcFieldIndex := srcStructField.Index
srcPropertyName := proptools.PropertyNameForField(srcField)
srcsSupplier := func() []string {
srcsSupplier := func(ctx BaseModuleContext) []string {
value := srcPropsValue.FieldByIndex(srcFieldIndex)
if value.Kind() == reflect.Ptr {
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
// will be used if it is marked "prefer" or if the source module is disabled.
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
}

View file

@ -5597,6 +5597,36 @@ func TestAppSetBundle(t *testing.T) {
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)) {
t.Helper()

View file

@ -50,6 +50,10 @@ type prebuiltCommon struct {
properties prebuiltCommonProperties
}
type sanitizedPrebuilt interface {
hasSanitizedSource(sanitizer string) bool
}
type prebuiltCommonProperties struct {
ForceDisable bool `blueprint:"mutated"`
}
@ -75,9 +79,10 @@ func (p *prebuiltCommon) checkForceDisable(ctx android.ModuleContext) bool {
forceDisable = forceDisable || ctx.DeviceConfig().NativeCoverageEnabled()
forceDisable = forceDisable || ctx.Config().IsEnvTrue("EMMA_INSTRUMENT")
// b/137216042 don't use prebuilts when address sanitizer is on
forceDisable = forceDisable || android.InList("address", ctx.Config().SanitizeDevice()) ||
android.InList("hwaddress", ctx.Config().SanitizeDevice())
// b/137216042 don't use prebuilts when address sanitizer is on, unless the prebuilt has a sanitized source
sanitized := ctx.Module().(sanitizedPrebuilt)
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() {
p.properties.ForceDisable = true
@ -135,6 +140,10 @@ type PrebuiltProperties struct {
Overrides []string
}
func (a *Prebuilt) hasSanitizedSource(sanitizer string) bool {
return false
}
func (p *Prebuilt) installable() bool {
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.
Set *string
Sanitized struct {
None struct {
Set *string
}
Address struct {
Set *string
}
Hwaddress struct {
Set *string
}
}
// whether the extracted apex file installable.
Installable *bool
@ -284,6 +305,41 @@ type ApexSetProperties struct {
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 {
return a.properties.Installable == nil || proptools.Bool(a.properties.Installable)
}
@ -304,7 +360,12 @@ func (a *ApexSet) Overrides() []string {
func apexSetFactory() android.Module {
module := &ApexSet{}
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)
return module
}

View file

@ -121,7 +121,10 @@ type SharedProperties 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"`
Enabled *bool `android:"arch_variant"`

View file

@ -38,10 +38,11 @@ type prebuiltLinkerInterface interface {
}
type prebuiltLinkerProperties struct {
// a prebuilt library or binary. Can reference a genrule module that generates an executable file.
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
// symbols, etc), default true.
Check_elf_files *bool
@ -105,7 +106,7 @@ func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
// TODO(ccross): verify shared library dependencies
srcs := p.prebuiltSrcs()
srcs := p.prebuiltSrcs(ctx)
if len(srcs) > 0 {
builderFlags := flagsToBuilderFlags(flags)
@ -177,15 +178,18 @@ func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
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 = append(srcs, srcsForSanitizer(sanitize, p.properties.Sanitized)...)
if p.static() {
srcs = append(srcs, p.libraryDecorator.StaticProperties.Static.Srcs...)
srcs = append(srcs, srcsForSanitizer(sanitize, p.libraryDecorator.StaticProperties.Static.Sanitized)...)
}
if p.shared() {
srcs = append(srcs, p.libraryDecorator.SharedProperties.Shared.Srcs...)
srcs = append(srcs, srcsForSanitizer(sanitize, p.libraryDecorator.SharedProperties.Shared.Sanitized)...)
}
return srcs
}
@ -212,8 +216,8 @@ func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDec
module.AddProperties(&prebuilt.properties)
srcsSupplier := func() []string {
return prebuilt.prebuiltSrcs()
srcsSupplier := func(ctx android.BaseModuleContext) []string {
return prebuilt.prebuiltSrcs(ctx)
}
android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "srcs")
@ -425,3 +429,28 @@ func NewPrebuiltBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecor
android.InitPrebuiltModule(module, &prebuilt.properties.Srcs)
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"
)
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)
ctx := CreateTestContext()
@ -34,6 +34,10 @@ func testPrebuilt(t *testing.T, bp string, fs map[string][]byte) *android.TestCo
android.RegisterAndroidMkBuildComponents(ctx)
android.SetInMakeForTests(config)
for _, handler := range handlers {
handler(config)
}
ctx.Register(config)
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
android.FailIfErrored(t, errs)
@ -42,6 +46,8 @@ func testPrebuilt(t *testing.T, bp string, fs map[string][]byte) *android.TestCo
return ctx
}
type configCustomizer func(config android.Config)
func TestPrebuilt(t *testing.T) {
bp := `
cc_library {
@ -321,3 +327,62 @@ func TestPrebuiltSymlinkedHostBinary(t *testing.T) {
assertString(t, libfooDep.String(),
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")
}