diff --git a/cc/androidmk.go b/cc/androidmk.go index c9d4dadb0..aab4edd93 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -303,6 +303,33 @@ func (test *testBinary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkDa androidMkWriteTestData(test.data, ctx, ret) } +func (fuzz *fuzzBinary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { + ctx.subAndroidMk(ret, fuzz.binaryDecorator) + + var fuzzFiles []string + for _, d := range fuzz.corpus { + rel := d.Rel() + path := d.String() + path = strings.TrimSuffix(path, rel) + fuzzFiles = append(fuzzFiles, path+":corpus/"+d.Base()) + } + + if fuzz.dictionary != nil { + path := strings.TrimSuffix(fuzz.dictionary.String(), fuzz.dictionary.Rel()) + fuzzFiles = append(fuzzFiles, path+":"+fuzz.dictionary.Base()) + } + + if len(fuzzFiles) > 0 { + ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { + fmt.Fprintln(w, "LOCAL_TEST_DATA := "+strings.Join(fuzzFiles, " ")) + }) + } + + ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { + fmt.Fprintln(w, "LOCAL_IS_FUZZ_TARGET := true") + }) +} + func (test *testLibrary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) { ctx.subAndroidMk(ret, test.libraryDecorator) } diff --git a/cc/cc.go b/cc/cc.go index cda37e8c1..b255a1455 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -2204,6 +2204,7 @@ func DefaultsFactory(props ...interface{}) android.Module { &BinaryLinkerProperties{}, &TestProperties{}, &TestBinaryProperties{}, + &FuzzProperties{}, &StlProperties{}, &SanitizeProperties{}, &StripProperties{}, diff --git a/cc/fuzz.go b/cc/fuzz.go index b0fb262df..325be6333 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -23,6 +23,14 @@ import ( "android/soong/cc/config" ) +type FuzzProperties struct { + // Optional list of seed files to be installed to the fuzz target's output + // directory. + Corpus []string `android:"path"` + // Optional dictionary to be installed to the fuzz target's output directory. + Dictionary *string `android:"path"` +} + func init() { android.RegisterModuleType("cc_fuzz", FuzzFactory) } @@ -42,10 +50,15 @@ func NewFuzzInstaller() *baseInstaller { type fuzzBinary struct { *binaryDecorator *baseCompiler + + Properties FuzzProperties + corpus android.Paths + dictionary android.Path } func (fuzz *fuzzBinary) linkerProps() []interface{} { props := fuzz.binaryDecorator.linkerProps() + props = append(props, &fuzz.Properties) return props } @@ -81,9 +94,21 @@ func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags { } func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) { - fuzz.binaryDecorator.baseInstaller.dir = filepath.Join("fuzz", ctx.Target().Arch.ArchType.String()) - fuzz.binaryDecorator.baseInstaller.dir64 = filepath.Join("fuzz", ctx.Target().Arch.ArchType.String()) + fuzz.binaryDecorator.baseInstaller.dir = filepath.Join( + "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) + fuzz.binaryDecorator.baseInstaller.dir64 = filepath.Join( + "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) fuzz.binaryDecorator.baseInstaller.install(ctx, file) + + fuzz.corpus = android.PathsForModuleSrc(ctx, fuzz.Properties.Corpus) + if fuzz.Properties.Dictionary != nil { + fuzz.dictionary = android.PathForModuleSrc(ctx, *fuzz.Properties.Dictionary) + if fuzz.dictionary.Ext() != ".dict" { + ctx.PropertyErrorf("dictionary", + "Fuzzer dictionary %q does not have '.dict' extension", + fuzz.dictionary.String()) + } + } } func NewFuzz(hod android.HostOrDeviceSupported) *Module {