blob: 325be63335909d8d65a7af02850f8d02c259789c [file] [log] [blame]
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001// Copyright 2016 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17import (
Mitch Phillips4de896e2019-08-28 16:04:36 -070018 "path/filepath"
19
20 "github.com/google/blueprint/proptools"
21
Mitch Phillipsda9a4632019-07-15 09:34:09 -070022 "android/soong/android"
23 "android/soong/cc/config"
24)
25
Mitch Phillips4e4ab8a2019-09-13 17:32:50 -070026type FuzzProperties struct {
27 // Optional list of seed files to be installed to the fuzz target's output
28 // directory.
29 Corpus []string `android:"path"`
30 // Optional dictionary to be installed to the fuzz target's output directory.
31 Dictionary *string `android:"path"`
32}
33
Mitch Phillipsda9a4632019-07-15 09:34:09 -070034func init() {
35 android.RegisterModuleType("cc_fuzz", FuzzFactory)
36}
37
38// cc_fuzz creates a host/device fuzzer binary. Host binaries can be found at
39// $ANDROID_HOST_OUT/fuzz/, and device binaries can be found at /data/fuzz on
40// your device, or $ANDROID_PRODUCT_OUT/data/fuzz in your build tree.
41func FuzzFactory() android.Module {
42 module := NewFuzz(android.HostAndDeviceSupported)
43 return module.Init()
44}
45
46func NewFuzzInstaller() *baseInstaller {
47 return NewBaseInstaller("fuzz", "fuzz", InstallInData)
48}
49
50type fuzzBinary struct {
51 *binaryDecorator
52 *baseCompiler
Mitch Phillips4e4ab8a2019-09-13 17:32:50 -070053
54 Properties FuzzProperties
55 corpus android.Paths
56 dictionary android.Path
Mitch Phillipsda9a4632019-07-15 09:34:09 -070057}
58
59func (fuzz *fuzzBinary) linkerProps() []interface{} {
60 props := fuzz.binaryDecorator.linkerProps()
Mitch Phillips4e4ab8a2019-09-13 17:32:50 -070061 props = append(props, &fuzz.Properties)
Mitch Phillipsda9a4632019-07-15 09:34:09 -070062 return props
63}
64
65func (fuzz *fuzzBinary) linkerInit(ctx BaseModuleContext) {
66 // Add ../lib[64] to rpath so that out/host/linux-x86/fuzz/<fuzzer> can
67 // find out/host/linux-x86/lib[64]/library.so
68 runpaths := []string{"../lib"}
69 for _, runpath := range runpaths {
70 if ctx.toolchain().Is64Bit() {
71 runpath += "64"
72 }
73 fuzz.binaryDecorator.baseLinker.dynamicProperties.RunPaths = append(
74 fuzz.binaryDecorator.baseLinker.dynamicProperties.RunPaths, runpath)
75 }
76
77 // add "" to rpath so that fuzzer binaries can find libraries in their own fuzz directory
78 fuzz.binaryDecorator.baseLinker.dynamicProperties.RunPaths = append(
79 fuzz.binaryDecorator.baseLinker.dynamicProperties.RunPaths, "")
80
81 fuzz.binaryDecorator.linkerInit(ctx)
82}
83
84func (fuzz *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps {
85 deps.StaticLibs = append(deps.StaticLibs,
86 config.LibFuzzerRuntimeLibrary(ctx.toolchain()))
87 deps = fuzz.binaryDecorator.linkerDeps(ctx, deps)
88 return deps
89}
90
91func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
92 flags = fuzz.binaryDecorator.linkerFlags(ctx, flags)
93 return flags
94}
95
96func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) {
Mitch Phillips4e4ab8a2019-09-13 17:32:50 -070097 fuzz.binaryDecorator.baseInstaller.dir = filepath.Join(
98 "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
99 fuzz.binaryDecorator.baseInstaller.dir64 = filepath.Join(
100 "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
Mitch Phillipsda9a4632019-07-15 09:34:09 -0700101 fuzz.binaryDecorator.baseInstaller.install(ctx, file)
Mitch Phillips4e4ab8a2019-09-13 17:32:50 -0700102
103 fuzz.corpus = android.PathsForModuleSrc(ctx, fuzz.Properties.Corpus)
104 if fuzz.Properties.Dictionary != nil {
105 fuzz.dictionary = android.PathForModuleSrc(ctx, *fuzz.Properties.Dictionary)
106 if fuzz.dictionary.Ext() != ".dict" {
107 ctx.PropertyErrorf("dictionary",
108 "Fuzzer dictionary %q does not have '.dict' extension",
109 fuzz.dictionary.String())
110 }
111 }
Mitch Phillipsda9a4632019-07-15 09:34:09 -0700112}
113
114func NewFuzz(hod android.HostOrDeviceSupported) *Module {
115 module, binary := NewBinary(hod)
116
Mitch Phillipsda9a4632019-07-15 09:34:09 -0700117 binary.baseInstaller = NewFuzzInstaller()
118 module.sanitize.SetSanitizer(fuzzer, true)
119
120 fuzz := &fuzzBinary{
121 binaryDecorator: binary,
122 baseCompiler: NewBaseCompiler(),
123 }
124 module.compiler = fuzz
125 module.linker = fuzz
126 module.installer = fuzz
Colin Crosseec9b282019-07-18 16:20:52 -0700127
128 // The fuzzer runtime is not present for darwin host modules, disable cc_fuzz modules when targeting darwin.
129 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
Alex Light71123ec2019-07-24 13:34:19 -0700130 disableDarwinAndLinuxBionic := struct {
Colin Crosseec9b282019-07-18 16:20:52 -0700131 Target struct {
132 Darwin struct {
133 Enabled *bool
134 }
Alex Light71123ec2019-07-24 13:34:19 -0700135 Linux_bionic struct {
136 Enabled *bool
137 }
Colin Crosseec9b282019-07-18 16:20:52 -0700138 }
139 }{}
Alex Light71123ec2019-07-24 13:34:19 -0700140 disableDarwinAndLinuxBionic.Target.Darwin.Enabled = BoolPtr(false)
141 disableDarwinAndLinuxBionic.Target.Linux_bionic.Enabled = BoolPtr(false)
142 ctx.AppendProperties(&disableDarwinAndLinuxBionic)
Colin Crosseec9b282019-07-18 16:20:52 -0700143 })
144
Mitch Phillipsd0bd16d2019-08-22 15:47:09 -0700145 // Statically link the STL. This allows fuzz target deployment to not have to
146 // include the STL.
147 android.AddLoadHook(module, func(ctx android.LoadHookContext) {
148 staticStlLinkage := struct {
149 Stl *string
150 }{}
151
152 staticStlLinkage.Stl = proptools.StringPtr("libc++_static")
153 ctx.AppendProperties(&staticStlLinkage)
154 })
155
Mitch Phillipsda9a4632019-07-15 09:34:09 -0700156 return module
157}