xref: /aosp_15_r20/build/soong/cc/sanitize.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2016 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage cc
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"fmt"
19*333d2b36SAndroid Build Coastguard Worker	"sort"
20*333d2b36SAndroid Build Coastguard Worker	"strings"
21*333d2b36SAndroid Build Coastguard Worker	"sync"
22*333d2b36SAndroid Build Coastguard Worker
23*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
24*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
25*333d2b36SAndroid Build Coastguard Worker
26*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
27*333d2b36SAndroid Build Coastguard Worker	"android/soong/cc/config"
28*333d2b36SAndroid Build Coastguard Worker	"android/soong/etc"
29*333d2b36SAndroid Build Coastguard Worker)
30*333d2b36SAndroid Build Coastguard Worker
31*333d2b36SAndroid Build Coastguard Workervar (
32*333d2b36SAndroid Build Coastguard Worker	// Any C flags added by sanitizer which libTooling tools may not
33*333d2b36SAndroid Build Coastguard Worker	// understand also need to be added to ClangLibToolingUnknownCflags in
34*333d2b36SAndroid Build Coastguard Worker	// cc/config/clang.go
35*333d2b36SAndroid Build Coastguard Worker
36*333d2b36SAndroid Build Coastguard Worker	asanCflags = []string{
37*333d2b36SAndroid Build Coastguard Worker		"-fno-omit-frame-pointer",
38*333d2b36SAndroid Build Coastguard Worker	}
39*333d2b36SAndroid Build Coastguard Worker
40*333d2b36SAndroid Build Coastguard Worker	// DO NOT ADD MLLVM FLAGS HERE! ADD THEM BELOW TO hwasanCommonFlags.
41*333d2b36SAndroid Build Coastguard Worker	hwasanCflags = []string{
42*333d2b36SAndroid Build Coastguard Worker		"-fno-omit-frame-pointer",
43*333d2b36SAndroid Build Coastguard Worker		"-Wno-frame-larger-than=",
44*333d2b36SAndroid Build Coastguard Worker		"-fsanitize-hwaddress-abi=platform",
45*333d2b36SAndroid Build Coastguard Worker	}
46*333d2b36SAndroid Build Coastguard Worker
47*333d2b36SAndroid Build Coastguard Worker	// ThinLTO performs codegen during link time, thus these flags need to
48*333d2b36SAndroid Build Coastguard Worker	// passed to both CFLAGS and LDFLAGS.
49*333d2b36SAndroid Build Coastguard Worker	hwasanCommonflags = []string{
50*333d2b36SAndroid Build Coastguard Worker		// The following improves debug location information
51*333d2b36SAndroid Build Coastguard Worker		// availability at the cost of its accuracy. It increases
52*333d2b36SAndroid Build Coastguard Worker		// the likelihood of a stack variable's frame offset
53*333d2b36SAndroid Build Coastguard Worker		// to be recorded in the debug info, which is important
54*333d2b36SAndroid Build Coastguard Worker		// for the quality of hwasan reports. The downside is a
55*333d2b36SAndroid Build Coastguard Worker		// higher number of "optimized out" stack variables.
56*333d2b36SAndroid Build Coastguard Worker		// b/112437883.
57*333d2b36SAndroid Build Coastguard Worker		"-instcombine-lower-dbg-declare=0",
58*333d2b36SAndroid Build Coastguard Worker		"-dom-tree-reachability-max-bbs-to-explore=128",
59*333d2b36SAndroid Build Coastguard Worker	}
60*333d2b36SAndroid Build Coastguard Worker
61*333d2b36SAndroid Build Coastguard Worker	sanitizeIgnorelistPrefix = "-fsanitize-ignorelist="
62*333d2b36SAndroid Build Coastguard Worker
63*333d2b36SAndroid Build Coastguard Worker	cfiBlocklistPath     = "external/compiler-rt/lib/cfi"
64*333d2b36SAndroid Build Coastguard Worker	cfiBlocklistFilename = "cfi_blocklist.txt"
65*333d2b36SAndroid Build Coastguard Worker	cfiEnableFlag        = "-fsanitize=cfi"
66*333d2b36SAndroid Build Coastguard Worker	cfiCrossDsoFlag      = "-fsanitize-cfi-cross-dso"
67*333d2b36SAndroid Build Coastguard Worker	cfiCflags            = []string{"-flto", cfiCrossDsoFlag,
68*333d2b36SAndroid Build Coastguard Worker		sanitizeIgnorelistPrefix + cfiBlocklistPath + "/" + cfiBlocklistFilename}
69*333d2b36SAndroid Build Coastguard Worker	// -flto and -fvisibility are required by clang when -fsanitize=cfi is
70*333d2b36SAndroid Build Coastguard Worker	// used, but have no effect on assembly files
71*333d2b36SAndroid Build Coastguard Worker	cfiAsflags = []string{"-flto", "-fvisibility=default"}
72*333d2b36SAndroid Build Coastguard Worker	cfiLdflags = []string{"-flto", cfiCrossDsoFlag, cfiEnableFlag,
73*333d2b36SAndroid Build Coastguard Worker		"-Wl,-plugin-opt,O1"}
74*333d2b36SAndroid Build Coastguard Worker	cfiExportsMapPath      = "build/soong/cc/config"
75*333d2b36SAndroid Build Coastguard Worker	cfiExportsMapFilename  = "cfi_exports.map"
76*333d2b36SAndroid Build Coastguard Worker	cfiAssemblySupportFlag = "-fno-sanitize-cfi-canonical-jump-tables"
77*333d2b36SAndroid Build Coastguard Worker
78*333d2b36SAndroid Build Coastguard Worker	intOverflowCflags = []string{"-fsanitize-ignorelist=build/soong/cc/config/integer_overflow_blocklist.txt"}
79*333d2b36SAndroid Build Coastguard Worker
80*333d2b36SAndroid Build Coastguard Worker	minimalRuntimeFlags = []string{"-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
81*333d2b36SAndroid Build Coastguard Worker		"-fno-sanitize-recover=integer,undefined"}
82*333d2b36SAndroid Build Coastguard Worker	memtagStackCommonFlags = []string{"-march=armv8-a+memtag"}
83*333d2b36SAndroid Build Coastguard Worker	memtagStackLlvmFlags   = []string{"-dom-tree-reachability-max-bbs-to-explore=128"}
84*333d2b36SAndroid Build Coastguard Worker
85*333d2b36SAndroid Build Coastguard Worker	hostOnlySanitizeFlags   = []string{"-fno-sanitize-recover=all"}
86*333d2b36SAndroid Build Coastguard Worker	deviceOnlySanitizeFlags = []string{"-fsanitize-trap=all"}
87*333d2b36SAndroid Build Coastguard Worker
88*333d2b36SAndroid Build Coastguard Worker	noSanitizeLinkRuntimeFlag = "-fno-sanitize-link-runtime"
89*333d2b36SAndroid Build Coastguard Worker)
90*333d2b36SAndroid Build Coastguard Worker
91*333d2b36SAndroid Build Coastguard Workertype SanitizerType int
92*333d2b36SAndroid Build Coastguard Worker
93*333d2b36SAndroid Build Coastguard Workerconst (
94*333d2b36SAndroid Build Coastguard Worker	Asan SanitizerType = iota + 1
95*333d2b36SAndroid Build Coastguard Worker	Hwasan
96*333d2b36SAndroid Build Coastguard Worker	tsan
97*333d2b36SAndroid Build Coastguard Worker	intOverflow
98*333d2b36SAndroid Build Coastguard Worker	scs
99*333d2b36SAndroid Build Coastguard Worker	Fuzzer
100*333d2b36SAndroid Build Coastguard Worker	Memtag_heap
101*333d2b36SAndroid Build Coastguard Worker	Memtag_stack
102*333d2b36SAndroid Build Coastguard Worker	Memtag_globals
103*333d2b36SAndroid Build Coastguard Worker	cfi // cfi is last to prevent it running before incompatible mutators
104*333d2b36SAndroid Build Coastguard Worker)
105*333d2b36SAndroid Build Coastguard Worker
106*333d2b36SAndroid Build Coastguard Workervar Sanitizers = []SanitizerType{
107*333d2b36SAndroid Build Coastguard Worker	Asan,
108*333d2b36SAndroid Build Coastguard Worker	Hwasan,
109*333d2b36SAndroid Build Coastguard Worker	tsan,
110*333d2b36SAndroid Build Coastguard Worker	intOverflow,
111*333d2b36SAndroid Build Coastguard Worker	scs,
112*333d2b36SAndroid Build Coastguard Worker	Fuzzer,
113*333d2b36SAndroid Build Coastguard Worker	Memtag_heap,
114*333d2b36SAndroid Build Coastguard Worker	Memtag_stack,
115*333d2b36SAndroid Build Coastguard Worker	Memtag_globals,
116*333d2b36SAndroid Build Coastguard Worker	cfi, // cfi is last to prevent it running before incompatible mutators
117*333d2b36SAndroid Build Coastguard Worker}
118*333d2b36SAndroid Build Coastguard Worker
119*333d2b36SAndroid Build Coastguard Worker// Name of the sanitizer variation for this sanitizer type
120*333d2b36SAndroid Build Coastguard Workerfunc (t SanitizerType) variationName() string {
121*333d2b36SAndroid Build Coastguard Worker	switch t {
122*333d2b36SAndroid Build Coastguard Worker	case Asan:
123*333d2b36SAndroid Build Coastguard Worker		return "asan"
124*333d2b36SAndroid Build Coastguard Worker	case Hwasan:
125*333d2b36SAndroid Build Coastguard Worker		return "hwasan"
126*333d2b36SAndroid Build Coastguard Worker	case tsan:
127*333d2b36SAndroid Build Coastguard Worker		return "tsan"
128*333d2b36SAndroid Build Coastguard Worker	case intOverflow:
129*333d2b36SAndroid Build Coastguard Worker		return "intOverflow"
130*333d2b36SAndroid Build Coastguard Worker	case cfi:
131*333d2b36SAndroid Build Coastguard Worker		return "cfi"
132*333d2b36SAndroid Build Coastguard Worker	case scs:
133*333d2b36SAndroid Build Coastguard Worker		return "scs"
134*333d2b36SAndroid Build Coastguard Worker	case Memtag_heap:
135*333d2b36SAndroid Build Coastguard Worker		return "memtag_heap"
136*333d2b36SAndroid Build Coastguard Worker	case Memtag_stack:
137*333d2b36SAndroid Build Coastguard Worker		return "memtag_stack"
138*333d2b36SAndroid Build Coastguard Worker	case Memtag_globals:
139*333d2b36SAndroid Build Coastguard Worker		return "memtag_globals"
140*333d2b36SAndroid Build Coastguard Worker	case Fuzzer:
141*333d2b36SAndroid Build Coastguard Worker		return "fuzzer"
142*333d2b36SAndroid Build Coastguard Worker	default:
143*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("unknown SanitizerType %d", t))
144*333d2b36SAndroid Build Coastguard Worker	}
145*333d2b36SAndroid Build Coastguard Worker}
146*333d2b36SAndroid Build Coastguard Worker
147*333d2b36SAndroid Build Coastguard Worker// This is the sanitizer names in SANITIZE_[TARGET|HOST]
148*333d2b36SAndroid Build Coastguard Workerfunc (t SanitizerType) name() string {
149*333d2b36SAndroid Build Coastguard Worker	switch t {
150*333d2b36SAndroid Build Coastguard Worker	case Asan:
151*333d2b36SAndroid Build Coastguard Worker		return "address"
152*333d2b36SAndroid Build Coastguard Worker	case Hwasan:
153*333d2b36SAndroid Build Coastguard Worker		return "hwaddress"
154*333d2b36SAndroid Build Coastguard Worker	case Memtag_heap:
155*333d2b36SAndroid Build Coastguard Worker		return "memtag_heap"
156*333d2b36SAndroid Build Coastguard Worker	case Memtag_stack:
157*333d2b36SAndroid Build Coastguard Worker		return "memtag_stack"
158*333d2b36SAndroid Build Coastguard Worker	case Memtag_globals:
159*333d2b36SAndroid Build Coastguard Worker		return "memtag_globals"
160*333d2b36SAndroid Build Coastguard Worker	case tsan:
161*333d2b36SAndroid Build Coastguard Worker		return "thread"
162*333d2b36SAndroid Build Coastguard Worker	case intOverflow:
163*333d2b36SAndroid Build Coastguard Worker		return "integer_overflow"
164*333d2b36SAndroid Build Coastguard Worker	case cfi:
165*333d2b36SAndroid Build Coastguard Worker		return "cfi"
166*333d2b36SAndroid Build Coastguard Worker	case scs:
167*333d2b36SAndroid Build Coastguard Worker		return "shadow-call-stack"
168*333d2b36SAndroid Build Coastguard Worker	case Fuzzer:
169*333d2b36SAndroid Build Coastguard Worker		return "fuzzer"
170*333d2b36SAndroid Build Coastguard Worker	default:
171*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("unknown SanitizerType %d", t))
172*333d2b36SAndroid Build Coastguard Worker	}
173*333d2b36SAndroid Build Coastguard Worker}
174*333d2b36SAndroid Build Coastguard Worker
175*333d2b36SAndroid Build Coastguard Workerfunc (t SanitizerType) registerMutators(ctx android.RegisterMutatorsContext) {
176*333d2b36SAndroid Build Coastguard Worker	switch t {
177*333d2b36SAndroid Build Coastguard Worker	case cfi, Hwasan, Asan, tsan, Fuzzer, scs, Memtag_stack:
178*333d2b36SAndroid Build Coastguard Worker		sanitizer := &sanitizerSplitMutator{t}
179*333d2b36SAndroid Build Coastguard Worker		ctx.BottomUp(t.variationName()+"_markapexes", sanitizer.markSanitizableApexesMutator)
180*333d2b36SAndroid Build Coastguard Worker		ctx.Transition(t.variationName(), sanitizer)
181*333d2b36SAndroid Build Coastguard Worker	case Memtag_heap, Memtag_globals, intOverflow:
182*333d2b36SAndroid Build Coastguard Worker		// do nothing
183*333d2b36SAndroid Build Coastguard Worker	default:
184*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("unknown SanitizerType %d", t))
185*333d2b36SAndroid Build Coastguard Worker	}
186*333d2b36SAndroid Build Coastguard Worker}
187*333d2b36SAndroid Build Coastguard Worker
188*333d2b36SAndroid Build Coastguard Worker// shouldPropagateToSharedLibraryDeps returns whether a sanitizer type should propagate to share
189*333d2b36SAndroid Build Coastguard Worker// dependencies. In most cases, sanitizers only propagate to static dependencies; however, some
190*333d2b36SAndroid Build Coastguard Worker// sanitizers also must be enabled for shared libraries for linking.
191*333d2b36SAndroid Build Coastguard Workerfunc (t SanitizerType) shouldPropagateToSharedLibraryDeps() bool {
192*333d2b36SAndroid Build Coastguard Worker	switch t {
193*333d2b36SAndroid Build Coastguard Worker	case Fuzzer:
194*333d2b36SAndroid Build Coastguard Worker		// Typically, shared libs are not split. However, for fuzzer, we split even for shared libs
195*333d2b36SAndroid Build Coastguard Worker		// because a library sanitized for fuzzer can't be linked from a library that isn't sanitized
196*333d2b36SAndroid Build Coastguard Worker		// for fuzzer.
197*333d2b36SAndroid Build Coastguard Worker		return true
198*333d2b36SAndroid Build Coastguard Worker	default:
199*333d2b36SAndroid Build Coastguard Worker		return false
200*333d2b36SAndroid Build Coastguard Worker	}
201*333d2b36SAndroid Build Coastguard Worker}
202*333d2b36SAndroid Build Coastguard Workerfunc (*Module) SanitizerSupported(t SanitizerType) bool {
203*333d2b36SAndroid Build Coastguard Worker	switch t {
204*333d2b36SAndroid Build Coastguard Worker	case Asan:
205*333d2b36SAndroid Build Coastguard Worker		return true
206*333d2b36SAndroid Build Coastguard Worker	case Hwasan:
207*333d2b36SAndroid Build Coastguard Worker		return true
208*333d2b36SAndroid Build Coastguard Worker	case tsan:
209*333d2b36SAndroid Build Coastguard Worker		return true
210*333d2b36SAndroid Build Coastguard Worker	case intOverflow:
211*333d2b36SAndroid Build Coastguard Worker		return true
212*333d2b36SAndroid Build Coastguard Worker	case cfi:
213*333d2b36SAndroid Build Coastguard Worker		return true
214*333d2b36SAndroid Build Coastguard Worker	case scs:
215*333d2b36SAndroid Build Coastguard Worker		return true
216*333d2b36SAndroid Build Coastguard Worker	case Fuzzer:
217*333d2b36SAndroid Build Coastguard Worker		return true
218*333d2b36SAndroid Build Coastguard Worker	case Memtag_heap:
219*333d2b36SAndroid Build Coastguard Worker		return true
220*333d2b36SAndroid Build Coastguard Worker	case Memtag_stack:
221*333d2b36SAndroid Build Coastguard Worker		return true
222*333d2b36SAndroid Build Coastguard Worker	case Memtag_globals:
223*333d2b36SAndroid Build Coastguard Worker		return true
224*333d2b36SAndroid Build Coastguard Worker	default:
225*333d2b36SAndroid Build Coastguard Worker		return false
226*333d2b36SAndroid Build Coastguard Worker	}
227*333d2b36SAndroid Build Coastguard Worker}
228*333d2b36SAndroid Build Coastguard Worker
229*333d2b36SAndroid Build Coastguard Worker// incompatibleWithCfi returns true if a sanitizer is incompatible with CFI.
230*333d2b36SAndroid Build Coastguard Workerfunc (t SanitizerType) incompatibleWithCfi() bool {
231*333d2b36SAndroid Build Coastguard Worker	return t == Asan || t == Fuzzer || t == Hwasan
232*333d2b36SAndroid Build Coastguard Worker}
233*333d2b36SAndroid Build Coastguard Worker
234*333d2b36SAndroid Build Coastguard Workertype SanitizeUserProps struct {
235*333d2b36SAndroid Build Coastguard Worker	// Prevent use of any sanitizers on this module
236*333d2b36SAndroid Build Coastguard Worker	Never *bool `android:"arch_variant"`
237*333d2b36SAndroid Build Coastguard Worker
238*333d2b36SAndroid Build Coastguard Worker	// ASan (Address sanitizer), incompatible with static binaries.
239*333d2b36SAndroid Build Coastguard Worker	// Always runs in a diagnostic mode.
240*333d2b36SAndroid Build Coastguard Worker	// Use of address sanitizer disables cfi sanitizer.
241*333d2b36SAndroid Build Coastguard Worker	// Hwaddress sanitizer takes precedence over this sanitizer.
242*333d2b36SAndroid Build Coastguard Worker	Address *bool `android:"arch_variant"`
243*333d2b36SAndroid Build Coastguard Worker	// TSan (Thread sanitizer), incompatible with static binaries and 32 bit architectures.
244*333d2b36SAndroid Build Coastguard Worker	// Always runs in a diagnostic mode.
245*333d2b36SAndroid Build Coastguard Worker	// Use of thread sanitizer disables cfi and scudo sanitizers.
246*333d2b36SAndroid Build Coastguard Worker	// Hwaddress sanitizer takes precedence over this sanitizer.
247*333d2b36SAndroid Build Coastguard Worker	Thread *bool `android:"arch_variant"`
248*333d2b36SAndroid Build Coastguard Worker	// HWASan (Hardware Address sanitizer).
249*333d2b36SAndroid Build Coastguard Worker	// Use of hwasan sanitizer disables cfi, address, thread, and scudo sanitizers.
250*333d2b36SAndroid Build Coastguard Worker	Hwaddress *bool `android:"arch_variant"`
251*333d2b36SAndroid Build Coastguard Worker
252*333d2b36SAndroid Build Coastguard Worker	// Undefined behavior sanitizer
253*333d2b36SAndroid Build Coastguard Worker	All_undefined *bool `android:"arch_variant"`
254*333d2b36SAndroid Build Coastguard Worker	// Subset of undefined behavior sanitizer
255*333d2b36SAndroid Build Coastguard Worker	Undefined *bool `android:"arch_variant"`
256*333d2b36SAndroid Build Coastguard Worker	// List of specific undefined behavior sanitizers to enable
257*333d2b36SAndroid Build Coastguard Worker	Misc_undefined []string `android:"arch_variant"`
258*333d2b36SAndroid Build Coastguard Worker	// Fuzzer, incompatible with static binaries.
259*333d2b36SAndroid Build Coastguard Worker	Fuzzer *bool `android:"arch_variant"`
260*333d2b36SAndroid Build Coastguard Worker	// safe-stack sanitizer, incompatible with 32-bit architectures.
261*333d2b36SAndroid Build Coastguard Worker	Safestack *bool `android:"arch_variant"`
262*333d2b36SAndroid Build Coastguard Worker	// cfi sanitizer, incompatible with asan, hwasan, fuzzer, or Darwin
263*333d2b36SAndroid Build Coastguard Worker	Cfi *bool `android:"arch_variant"`
264*333d2b36SAndroid Build Coastguard Worker	// signed/unsigned integer overflow sanitizer, incompatible with Darwin.
265*333d2b36SAndroid Build Coastguard Worker	Integer_overflow *bool `android:"arch_variant"`
266*333d2b36SAndroid Build Coastguard Worker	// scudo sanitizer, incompatible with asan, hwasan, tsan
267*333d2b36SAndroid Build Coastguard Worker	// This should not be used in Android 11+ : https://source.android.com/devices/tech/debug/scudo
268*333d2b36SAndroid Build Coastguard Worker	// deprecated
269*333d2b36SAndroid Build Coastguard Worker	Scudo *bool `android:"arch_variant"`
270*333d2b36SAndroid Build Coastguard Worker	// shadow-call-stack sanitizer, only available on arm64/riscv64.
271*333d2b36SAndroid Build Coastguard Worker	Scs *bool `android:"arch_variant"`
272*333d2b36SAndroid Build Coastguard Worker	// Memory-tagging, only available on arm64
273*333d2b36SAndroid Build Coastguard Worker	// if diag.memtag unset or false, enables async memory tagging
274*333d2b36SAndroid Build Coastguard Worker	Memtag_heap *bool `android:"arch_variant"`
275*333d2b36SAndroid Build Coastguard Worker	// Memory-tagging stack instrumentation, only available on arm64
276*333d2b36SAndroid Build Coastguard Worker	// Adds instrumentation to detect stack buffer overflows and use-after-scope using MTE.
277*333d2b36SAndroid Build Coastguard Worker	Memtag_stack *bool `android:"arch_variant"`
278*333d2b36SAndroid Build Coastguard Worker	// Memory-tagging globals instrumentation, only available on arm64
279*333d2b36SAndroid Build Coastguard Worker	// Adds instrumentation to detect global buffer overflows using MTE.
280*333d2b36SAndroid Build Coastguard Worker	Memtag_globals *bool `android:"arch_variant"`
281*333d2b36SAndroid Build Coastguard Worker
282*333d2b36SAndroid Build Coastguard Worker	// A modifier for ASAN and HWASAN for write only instrumentation
283*333d2b36SAndroid Build Coastguard Worker	Writeonly *bool `android:"arch_variant"`
284*333d2b36SAndroid Build Coastguard Worker
285*333d2b36SAndroid Build Coastguard Worker	// Sanitizers to run in the diagnostic mode (as opposed to the release mode).
286*333d2b36SAndroid Build Coastguard Worker	// Replaces abort() on error with a human-readable error message.
287*333d2b36SAndroid Build Coastguard Worker	// Address and Thread sanitizers always run in diagnostic mode.
288*333d2b36SAndroid Build Coastguard Worker	Diag struct {
289*333d2b36SAndroid Build Coastguard Worker		// Undefined behavior sanitizer, diagnostic mode
290*333d2b36SAndroid Build Coastguard Worker		Undefined *bool `android:"arch_variant"`
291*333d2b36SAndroid Build Coastguard Worker		// cfi sanitizer, diagnostic mode, incompatible with asan, hwasan, fuzzer, or Darwin
292*333d2b36SAndroid Build Coastguard Worker		Cfi *bool `android:"arch_variant"`
293*333d2b36SAndroid Build Coastguard Worker		// signed/unsigned integer overflow sanitizer, diagnostic mode, incompatible with Darwin.
294*333d2b36SAndroid Build Coastguard Worker		Integer_overflow *bool `android:"arch_variant"`
295*333d2b36SAndroid Build Coastguard Worker		// Memory-tagging, only available on arm64
296*333d2b36SAndroid Build Coastguard Worker		// requires sanitizer.memtag: true
297*333d2b36SAndroid Build Coastguard Worker		// if set, enables sync memory tagging
298*333d2b36SAndroid Build Coastguard Worker		Memtag_heap *bool `android:"arch_variant"`
299*333d2b36SAndroid Build Coastguard Worker		// List of specific undefined behavior sanitizers to enable in diagnostic mode
300*333d2b36SAndroid Build Coastguard Worker		Misc_undefined []string `android:"arch_variant"`
301*333d2b36SAndroid Build Coastguard Worker		// List of sanitizers to pass to -fno-sanitize-recover
302*333d2b36SAndroid Build Coastguard Worker		// results in only the first detected error for these sanitizers being reported and program then
303*333d2b36SAndroid Build Coastguard Worker		// exits with a non-zero exit code.
304*333d2b36SAndroid Build Coastguard Worker		No_recover []string `android:"arch_variant"`
305*333d2b36SAndroid Build Coastguard Worker	} `android:"arch_variant"`
306*333d2b36SAndroid Build Coastguard Worker
307*333d2b36SAndroid Build Coastguard Worker	// Sanitizers to run with flag configuration specified
308*333d2b36SAndroid Build Coastguard Worker	Config struct {
309*333d2b36SAndroid Build Coastguard Worker		// Enables CFI support flags for assembly-heavy libraries
310*333d2b36SAndroid Build Coastguard Worker		Cfi_assembly_support *bool `android:"arch_variant"`
311*333d2b36SAndroid Build Coastguard Worker	} `android:"arch_variant"`
312*333d2b36SAndroid Build Coastguard Worker
313*333d2b36SAndroid Build Coastguard Worker	// List of sanitizers to pass to -fsanitize-recover
314*333d2b36SAndroid Build Coastguard Worker	// allows execution to continue for these sanitizers to detect multiple errors rather than only
315*333d2b36SAndroid Build Coastguard Worker	// the first one
316*333d2b36SAndroid Build Coastguard Worker	Recover []string
317*333d2b36SAndroid Build Coastguard Worker
318*333d2b36SAndroid Build Coastguard Worker	// value to pass to -fsanitize-ignorelist
319*333d2b36SAndroid Build Coastguard Worker	Blocklist *string
320*333d2b36SAndroid Build Coastguard Worker}
321*333d2b36SAndroid Build Coastguard Worker
322*333d2b36SAndroid Build Coastguard Workertype sanitizeMutatedProperties struct {
323*333d2b36SAndroid Build Coastguard Worker	// Whether sanitizers can be enabled on this module
324*333d2b36SAndroid Build Coastguard Worker	Never *bool `blueprint:"mutated"`
325*333d2b36SAndroid Build Coastguard Worker
326*333d2b36SAndroid Build Coastguard Worker	// Whether ASan (Address sanitizer) is enabled for this module.
327*333d2b36SAndroid Build Coastguard Worker	// Hwaddress sanitizer takes precedence over this sanitizer.
328*333d2b36SAndroid Build Coastguard Worker	Address *bool `blueprint:"mutated"`
329*333d2b36SAndroid Build Coastguard Worker	// Whether TSan (Thread sanitizer) is enabled for this module
330*333d2b36SAndroid Build Coastguard Worker	Thread *bool `blueprint:"mutated"`
331*333d2b36SAndroid Build Coastguard Worker	// Whether HWASan (Hardware Address sanitizer) is enabled for this module
332*333d2b36SAndroid Build Coastguard Worker	Hwaddress *bool `blueprint:"mutated"`
333*333d2b36SAndroid Build Coastguard Worker
334*333d2b36SAndroid Build Coastguard Worker	// Whether Undefined behavior sanitizer is enabled for this module
335*333d2b36SAndroid Build Coastguard Worker	All_undefined *bool `blueprint:"mutated"`
336*333d2b36SAndroid Build Coastguard Worker	// Whether undefined behavior sanitizer subset is enabled for this module
337*333d2b36SAndroid Build Coastguard Worker	Undefined *bool `blueprint:"mutated"`
338*333d2b36SAndroid Build Coastguard Worker	// List of specific undefined behavior sanitizers enabled for this module
339*333d2b36SAndroid Build Coastguard Worker	Misc_undefined []string `blueprint:"mutated"`
340*333d2b36SAndroid Build Coastguard Worker	// Whether Fuzzeris enabled for this module
341*333d2b36SAndroid Build Coastguard Worker	Fuzzer *bool `blueprint:"mutated"`
342*333d2b36SAndroid Build Coastguard Worker	// whether safe-stack sanitizer is enabled for this module
343*333d2b36SAndroid Build Coastguard Worker	Safestack *bool `blueprint:"mutated"`
344*333d2b36SAndroid Build Coastguard Worker	// Whether cfi sanitizer is enabled for this module
345*333d2b36SAndroid Build Coastguard Worker	Cfi *bool `blueprint:"mutated"`
346*333d2b36SAndroid Build Coastguard Worker	// Whether signed/unsigned integer overflow sanitizer is enabled for this module
347*333d2b36SAndroid Build Coastguard Worker	Integer_overflow *bool `blueprint:"mutated"`
348*333d2b36SAndroid Build Coastguard Worker	// Whether scudo sanitizer is enabled for this module
349*333d2b36SAndroid Build Coastguard Worker	Scudo *bool `blueprint:"mutated"`
350*333d2b36SAndroid Build Coastguard Worker	// Whether shadow-call-stack sanitizer is enabled for this module.
351*333d2b36SAndroid Build Coastguard Worker	Scs *bool `blueprint:"mutated"`
352*333d2b36SAndroid Build Coastguard Worker	// Whether Memory-tagging is enabled for this module
353*333d2b36SAndroid Build Coastguard Worker	Memtag_heap *bool `blueprint:"mutated"`
354*333d2b36SAndroid Build Coastguard Worker	// Whether Memory-tagging stack instrumentation is enabled for this module
355*333d2b36SAndroid Build Coastguard Worker	Memtag_stack *bool `blueprint:"mutated"`
356*333d2b36SAndroid Build Coastguard Worker	// Whether Memory-tagging globals instrumentation is enabled for this module
357*333d2b36SAndroid Build Coastguard Worker	Memtag_globals *bool `android:"arch_variant"`
358*333d2b36SAndroid Build Coastguard Worker
359*333d2b36SAndroid Build Coastguard Worker	// Whether a modifier for ASAN and HWASAN for write only instrumentation is enabled for this
360*333d2b36SAndroid Build Coastguard Worker	// module
361*333d2b36SAndroid Build Coastguard Worker	Writeonly *bool `blueprint:"mutated"`
362*333d2b36SAndroid Build Coastguard Worker
363*333d2b36SAndroid Build Coastguard Worker	// Sanitizers to run in the diagnostic mode (as opposed to the release mode).
364*333d2b36SAndroid Build Coastguard Worker	Diag struct {
365*333d2b36SAndroid Build Coastguard Worker		// Whether Undefined behavior sanitizer, diagnostic mode is enabled for this module
366*333d2b36SAndroid Build Coastguard Worker		Undefined *bool `blueprint:"mutated"`
367*333d2b36SAndroid Build Coastguard Worker		// Whether cfi sanitizer, diagnostic mode is enabled for this module
368*333d2b36SAndroid Build Coastguard Worker		Cfi *bool `blueprint:"mutated"`
369*333d2b36SAndroid Build Coastguard Worker		// Whether signed/unsigned integer overflow sanitizer, diagnostic mode is enabled for this
370*333d2b36SAndroid Build Coastguard Worker		// module
371*333d2b36SAndroid Build Coastguard Worker		Integer_overflow *bool `blueprint:"mutated"`
372*333d2b36SAndroid Build Coastguard Worker		// Whether Memory-tagging, diagnostic mode is enabled for this module
373*333d2b36SAndroid Build Coastguard Worker		Memtag_heap *bool `blueprint:"mutated"`
374*333d2b36SAndroid Build Coastguard Worker		// List of specific undefined behavior sanitizers enabled in diagnostic mode
375*333d2b36SAndroid Build Coastguard Worker		Misc_undefined []string `blueprint:"mutated"`
376*333d2b36SAndroid Build Coastguard Worker	} `blueprint:"mutated"`
377*333d2b36SAndroid Build Coastguard Worker}
378*333d2b36SAndroid Build Coastguard Worker
379*333d2b36SAndroid Build Coastguard Workertype SanitizeProperties struct {
380*333d2b36SAndroid Build Coastguard Worker	Sanitize        SanitizeUserProps         `android:"arch_variant"`
381*333d2b36SAndroid Build Coastguard Worker	SanitizeMutated sanitizeMutatedProperties `blueprint:"mutated"`
382*333d2b36SAndroid Build Coastguard Worker
383*333d2b36SAndroid Build Coastguard Worker	// ForceDisable is set by the version mutator to disable sanitization of stubs variants
384*333d2b36SAndroid Build Coastguard Worker	ForceDisable bool `blueprint:"mutated"`
385*333d2b36SAndroid Build Coastguard Worker
386*333d2b36SAndroid Build Coastguard Worker	// SanitizerEnabled is set by begin() if any of the sanitize boolean properties are set after
387*333d2b36SAndroid Build Coastguard Worker	// applying the logic that enables globally enabled sanitizers and disables any unsupported
388*333d2b36SAndroid Build Coastguard Worker	// sanitizers.
389*333d2b36SAndroid Build Coastguard Worker	// TODO(b/349906293): this has some unintuitive behavior.  It is set in begin() before the sanitize
390*333d2b36SAndroid Build Coastguard Worker	//  mutator is run if any of the individual sanitizes  properties are set, and then the individual
391*333d2b36SAndroid Build Coastguard Worker	//  sanitize properties are cleared in the non-sanitized variants, but this value is never cleared.
392*333d2b36SAndroid Build Coastguard Worker	//  That results in SanitizerEnabled being set in variants that have no sanitizers enabled, causing
393*333d2b36SAndroid Build Coastguard Worker	//  some of the sanitizer logic in flags() to be applied to the non-sanitized variant.
394*333d2b36SAndroid Build Coastguard Worker	SanitizerEnabled bool `blueprint:"mutated"`
395*333d2b36SAndroid Build Coastguard Worker
396*333d2b36SAndroid Build Coastguard Worker	MinimalRuntimeDep bool     `blueprint:"mutated"`
397*333d2b36SAndroid Build Coastguard Worker	BuiltinsDep       bool     `blueprint:"mutated"`
398*333d2b36SAndroid Build Coastguard Worker	UbsanRuntimeDep   bool     `blueprint:"mutated"`
399*333d2b36SAndroid Build Coastguard Worker	InSanitizerDir    bool     `blueprint:"mutated"`
400*333d2b36SAndroid Build Coastguard Worker	Sanitizers        []string `blueprint:"mutated"`
401*333d2b36SAndroid Build Coastguard Worker	DiagSanitizers    []string `blueprint:"mutated"`
402*333d2b36SAndroid Build Coastguard Worker}
403*333d2b36SAndroid Build Coastguard Worker
404*333d2b36SAndroid Build Coastguard Workertype sanitize struct {
405*333d2b36SAndroid Build Coastguard Worker	Properties SanitizeProperties
406*333d2b36SAndroid Build Coastguard Worker}
407*333d2b36SAndroid Build Coastguard Worker
408*333d2b36SAndroid Build Coastguard Worker// Mark this tag with a check to see if apex dependency check should be skipped
409*333d2b36SAndroid Build Coastguard Workerfunc (t libraryDependencyTag) SkipApexAllowedDependenciesCheck() bool {
410*333d2b36SAndroid Build Coastguard Worker	return t.skipApexAllowedDependenciesCheck
411*333d2b36SAndroid Build Coastguard Worker}
412*333d2b36SAndroid Build Coastguard Worker
413*333d2b36SAndroid Build Coastguard Workervar _ android.SkipApexAllowedDependenciesCheck = (*libraryDependencyTag)(nil)
414*333d2b36SAndroid Build Coastguard Worker
415*333d2b36SAndroid Build Coastguard Workerfunc init() {
416*333d2b36SAndroid Build Coastguard Worker	pctx.StaticVariable("HostOnlySanitizeFlags", strings.Join(hostOnlySanitizeFlags, " "))
417*333d2b36SAndroid Build Coastguard Worker
418*333d2b36SAndroid Build Coastguard Worker	android.RegisterMakeVarsProvider(pctx, cfiMakeVarsProvider)
419*333d2b36SAndroid Build Coastguard Worker	android.RegisterMakeVarsProvider(pctx, hwasanMakeVarsProvider)
420*333d2b36SAndroid Build Coastguard Worker	android.RegisterMakeVarsProvider(pctx, memtagStackMakeVarsProvider)
421*333d2b36SAndroid Build Coastguard Worker
422*333d2b36SAndroid Build Coastguard Worker	RegisterSanitizerLibrariesTxtType(android.InitRegistrationContext)
423*333d2b36SAndroid Build Coastguard Worker}
424*333d2b36SAndroid Build Coastguard Worker
425*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) props() []interface{} {
426*333d2b36SAndroid Build Coastguard Worker	return []interface{}{&sanitize.Properties}
427*333d2b36SAndroid Build Coastguard Worker}
428*333d2b36SAndroid Build Coastguard Worker
429*333d2b36SAndroid Build Coastguard Workerfunc (p *sanitizeMutatedProperties) copyUserPropertiesToMutated(userProps *SanitizeUserProps) {
430*333d2b36SAndroid Build Coastguard Worker	p.Never = userProps.Never
431*333d2b36SAndroid Build Coastguard Worker	p.Address = userProps.Address
432*333d2b36SAndroid Build Coastguard Worker	p.All_undefined = userProps.All_undefined
433*333d2b36SAndroid Build Coastguard Worker	p.Cfi = userProps.Cfi
434*333d2b36SAndroid Build Coastguard Worker	p.Fuzzer = userProps.Fuzzer
435*333d2b36SAndroid Build Coastguard Worker	p.Hwaddress = userProps.Hwaddress
436*333d2b36SAndroid Build Coastguard Worker	p.Integer_overflow = userProps.Integer_overflow
437*333d2b36SAndroid Build Coastguard Worker	p.Memtag_heap = userProps.Memtag_heap
438*333d2b36SAndroid Build Coastguard Worker	p.Memtag_stack = userProps.Memtag_stack
439*333d2b36SAndroid Build Coastguard Worker	p.Memtag_globals = userProps.Memtag_globals
440*333d2b36SAndroid Build Coastguard Worker	p.Safestack = userProps.Safestack
441*333d2b36SAndroid Build Coastguard Worker	p.Scs = userProps.Scs
442*333d2b36SAndroid Build Coastguard Worker	p.Scudo = userProps.Scudo
443*333d2b36SAndroid Build Coastguard Worker	p.Thread = userProps.Thread
444*333d2b36SAndroid Build Coastguard Worker	p.Undefined = userProps.Undefined
445*333d2b36SAndroid Build Coastguard Worker	p.Writeonly = userProps.Writeonly
446*333d2b36SAndroid Build Coastguard Worker
447*333d2b36SAndroid Build Coastguard Worker	p.Misc_undefined = make([]string, 0, len(userProps.Misc_undefined))
448*333d2b36SAndroid Build Coastguard Worker	for _, v := range userProps.Misc_undefined {
449*333d2b36SAndroid Build Coastguard Worker		p.Misc_undefined = append(p.Misc_undefined, v)
450*333d2b36SAndroid Build Coastguard Worker	}
451*333d2b36SAndroid Build Coastguard Worker
452*333d2b36SAndroid Build Coastguard Worker	p.Diag.Cfi = userProps.Diag.Cfi
453*333d2b36SAndroid Build Coastguard Worker	p.Diag.Integer_overflow = userProps.Diag.Integer_overflow
454*333d2b36SAndroid Build Coastguard Worker	p.Diag.Memtag_heap = userProps.Diag.Memtag_heap
455*333d2b36SAndroid Build Coastguard Worker	p.Diag.Undefined = userProps.Diag.Undefined
456*333d2b36SAndroid Build Coastguard Worker
457*333d2b36SAndroid Build Coastguard Worker	p.Diag.Misc_undefined = make([]string, 0, len(userProps.Diag.Misc_undefined))
458*333d2b36SAndroid Build Coastguard Worker	for _, v := range userProps.Diag.Misc_undefined {
459*333d2b36SAndroid Build Coastguard Worker		p.Diag.Misc_undefined = append(p.Diag.Misc_undefined, v)
460*333d2b36SAndroid Build Coastguard Worker	}
461*333d2b36SAndroid Build Coastguard Worker}
462*333d2b36SAndroid Build Coastguard Worker
463*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) begin(ctx BaseModuleContext) {
464*333d2b36SAndroid Build Coastguard Worker	s := &sanitize.Properties.SanitizeMutated
465*333d2b36SAndroid Build Coastguard Worker	s.copyUserPropertiesToMutated(&sanitize.Properties.Sanitize)
466*333d2b36SAndroid Build Coastguard Worker
467*333d2b36SAndroid Build Coastguard Worker	if sanitize.Properties.ForceDisable {
468*333d2b36SAndroid Build Coastguard Worker		return
469*333d2b36SAndroid Build Coastguard Worker	}
470*333d2b36SAndroid Build Coastguard Worker
471*333d2b36SAndroid Build Coastguard Worker	// Don't apply sanitizers to NDK code.
472*333d2b36SAndroid Build Coastguard Worker	if ctx.useSdk() {
473*333d2b36SAndroid Build Coastguard Worker		s.Never = BoolPtr(true)
474*333d2b36SAndroid Build Coastguard Worker	}
475*333d2b36SAndroid Build Coastguard Worker
476*333d2b36SAndroid Build Coastguard Worker	// Never always wins.
477*333d2b36SAndroid Build Coastguard Worker	if Bool(s.Never) {
478*333d2b36SAndroid Build Coastguard Worker		return
479*333d2b36SAndroid Build Coastguard Worker	}
480*333d2b36SAndroid Build Coastguard Worker
481*333d2b36SAndroid Build Coastguard Worker	// cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap: false}).
482*333d2b36SAndroid Build Coastguard Worker	if ctx.testBinary() {
483*333d2b36SAndroid Build Coastguard Worker		if s.Memtag_heap == nil {
484*333d2b36SAndroid Build Coastguard Worker			s.Memtag_heap = proptools.BoolPtr(true)
485*333d2b36SAndroid Build Coastguard Worker		}
486*333d2b36SAndroid Build Coastguard Worker		if s.Diag.Memtag_heap == nil {
487*333d2b36SAndroid Build Coastguard Worker			s.Diag.Memtag_heap = proptools.BoolPtr(true)
488*333d2b36SAndroid Build Coastguard Worker		}
489*333d2b36SAndroid Build Coastguard Worker	}
490*333d2b36SAndroid Build Coastguard Worker
491*333d2b36SAndroid Build Coastguard Worker	var globalSanitizers []string
492*333d2b36SAndroid Build Coastguard Worker	var globalSanitizersDiag []string
493*333d2b36SAndroid Build Coastguard Worker
494*333d2b36SAndroid Build Coastguard Worker	if ctx.Host() {
495*333d2b36SAndroid Build Coastguard Worker		if !ctx.Windows() {
496*333d2b36SAndroid Build Coastguard Worker			globalSanitizers = ctx.Config().SanitizeHost()
497*333d2b36SAndroid Build Coastguard Worker		}
498*333d2b36SAndroid Build Coastguard Worker	} else {
499*333d2b36SAndroid Build Coastguard Worker		arches := ctx.Config().SanitizeDeviceArch()
500*333d2b36SAndroid Build Coastguard Worker		if len(arches) == 0 || inList(ctx.Arch().ArchType.Name, arches) {
501*333d2b36SAndroid Build Coastguard Worker			globalSanitizers = ctx.Config().SanitizeDevice()
502*333d2b36SAndroid Build Coastguard Worker			globalSanitizersDiag = ctx.Config().SanitizeDeviceDiag()
503*333d2b36SAndroid Build Coastguard Worker		}
504*333d2b36SAndroid Build Coastguard Worker	}
505*333d2b36SAndroid Build Coastguard Worker
506*333d2b36SAndroid Build Coastguard Worker	if len(globalSanitizers) > 0 {
507*333d2b36SAndroid Build Coastguard Worker		var found bool
508*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("undefined", globalSanitizers); found && s.All_undefined == nil {
509*333d2b36SAndroid Build Coastguard Worker			s.All_undefined = proptools.BoolPtr(true)
510*333d2b36SAndroid Build Coastguard Worker		}
511*333d2b36SAndroid Build Coastguard Worker
512*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("default-ub", globalSanitizers); found && s.Undefined == nil {
513*333d2b36SAndroid Build Coastguard Worker			s.Undefined = proptools.BoolPtr(true)
514*333d2b36SAndroid Build Coastguard Worker		}
515*333d2b36SAndroid Build Coastguard Worker
516*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("address", globalSanitizers); found && s.Address == nil {
517*333d2b36SAndroid Build Coastguard Worker			s.Address = proptools.BoolPtr(true)
518*333d2b36SAndroid Build Coastguard Worker		}
519*333d2b36SAndroid Build Coastguard Worker
520*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("thread", globalSanitizers); found && s.Thread == nil {
521*333d2b36SAndroid Build Coastguard Worker			s.Thread = proptools.BoolPtr(true)
522*333d2b36SAndroid Build Coastguard Worker		}
523*333d2b36SAndroid Build Coastguard Worker
524*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("fuzzer", globalSanitizers); found && s.Fuzzer == nil {
525*333d2b36SAndroid Build Coastguard Worker			s.Fuzzer = proptools.BoolPtr(true)
526*333d2b36SAndroid Build Coastguard Worker		}
527*333d2b36SAndroid Build Coastguard Worker
528*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("safe-stack", globalSanitizers); found && s.Safestack == nil {
529*333d2b36SAndroid Build Coastguard Worker			s.Safestack = proptools.BoolPtr(true)
530*333d2b36SAndroid Build Coastguard Worker		}
531*333d2b36SAndroid Build Coastguard Worker
532*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("cfi", globalSanitizers); found && s.Cfi == nil {
533*333d2b36SAndroid Build Coastguard Worker			if !ctx.Config().CFIDisabledForPath(ctx.ModuleDir()) {
534*333d2b36SAndroid Build Coastguard Worker				s.Cfi = proptools.BoolPtr(true)
535*333d2b36SAndroid Build Coastguard Worker			}
536*333d2b36SAndroid Build Coastguard Worker		}
537*333d2b36SAndroid Build Coastguard Worker
538*333d2b36SAndroid Build Coastguard Worker		// Global integer_overflow builds do not support static libraries.
539*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("integer_overflow", globalSanitizers); found && s.Integer_overflow == nil {
540*333d2b36SAndroid Build Coastguard Worker			if !ctx.Config().IntegerOverflowDisabledForPath(ctx.ModuleDir()) && !ctx.static() {
541*333d2b36SAndroid Build Coastguard Worker				s.Integer_overflow = proptools.BoolPtr(true)
542*333d2b36SAndroid Build Coastguard Worker			}
543*333d2b36SAndroid Build Coastguard Worker		}
544*333d2b36SAndroid Build Coastguard Worker
545*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("scudo", globalSanitizers); found && s.Scudo == nil {
546*333d2b36SAndroid Build Coastguard Worker			s.Scudo = proptools.BoolPtr(true)
547*333d2b36SAndroid Build Coastguard Worker		}
548*333d2b36SAndroid Build Coastguard Worker
549*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("hwaddress", globalSanitizers); found && s.Hwaddress == nil {
550*333d2b36SAndroid Build Coastguard Worker			if !ctx.Config().HWASanDisabledForPath(ctx.ModuleDir()) {
551*333d2b36SAndroid Build Coastguard Worker				s.Hwaddress = proptools.BoolPtr(true)
552*333d2b36SAndroid Build Coastguard Worker			}
553*333d2b36SAndroid Build Coastguard Worker		}
554*333d2b36SAndroid Build Coastguard Worker
555*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("writeonly", globalSanitizers); found && s.Writeonly == nil {
556*333d2b36SAndroid Build Coastguard Worker			// Hwaddress and Address are set before, so we can check them here
557*333d2b36SAndroid Build Coastguard Worker			// If they aren't explicitly set in the blueprint/SANITIZE_(HOST|TARGET), they would be nil instead of false
558*333d2b36SAndroid Build Coastguard Worker			if s.Address == nil && s.Hwaddress == nil {
559*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("writeonly modifier cannot be used without 'address' or 'hwaddress'")
560*333d2b36SAndroid Build Coastguard Worker			}
561*333d2b36SAndroid Build Coastguard Worker			s.Writeonly = proptools.BoolPtr(true)
562*333d2b36SAndroid Build Coastguard Worker		}
563*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("memtag_heap", globalSanitizers); found && s.Memtag_heap == nil {
564*333d2b36SAndroid Build Coastguard Worker			if !ctx.Config().MemtagHeapDisabledForPath(ctx.ModuleDir()) {
565*333d2b36SAndroid Build Coastguard Worker				s.Memtag_heap = proptools.BoolPtr(true)
566*333d2b36SAndroid Build Coastguard Worker			}
567*333d2b36SAndroid Build Coastguard Worker		}
568*333d2b36SAndroid Build Coastguard Worker
569*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("memtag_stack", globalSanitizers); found && s.Memtag_stack == nil {
570*333d2b36SAndroid Build Coastguard Worker			s.Memtag_stack = proptools.BoolPtr(true)
571*333d2b36SAndroid Build Coastguard Worker		}
572*333d2b36SAndroid Build Coastguard Worker
573*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizers = removeFromList("memtag_globals", globalSanitizers); found && s.Memtag_globals == nil {
574*333d2b36SAndroid Build Coastguard Worker			s.Memtag_globals = proptools.BoolPtr(true)
575*333d2b36SAndroid Build Coastguard Worker		}
576*333d2b36SAndroid Build Coastguard Worker
577*333d2b36SAndroid Build Coastguard Worker		if len(globalSanitizers) > 0 {
578*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0])
579*333d2b36SAndroid Build Coastguard Worker		}
580*333d2b36SAndroid Build Coastguard Worker
581*333d2b36SAndroid Build Coastguard Worker		// Global integer_overflow builds do not support static library diagnostics.
582*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizersDiag = removeFromList("integer_overflow", globalSanitizersDiag); found &&
583*333d2b36SAndroid Build Coastguard Worker			s.Diag.Integer_overflow == nil && Bool(s.Integer_overflow) && !ctx.static() {
584*333d2b36SAndroid Build Coastguard Worker			s.Diag.Integer_overflow = proptools.BoolPtr(true)
585*333d2b36SAndroid Build Coastguard Worker		}
586*333d2b36SAndroid Build Coastguard Worker
587*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizersDiag = removeFromList("cfi", globalSanitizersDiag); found &&
588*333d2b36SAndroid Build Coastguard Worker			s.Diag.Cfi == nil && Bool(s.Cfi) {
589*333d2b36SAndroid Build Coastguard Worker			s.Diag.Cfi = proptools.BoolPtr(true)
590*333d2b36SAndroid Build Coastguard Worker		}
591*333d2b36SAndroid Build Coastguard Worker
592*333d2b36SAndroid Build Coastguard Worker		if found, globalSanitizersDiag = removeFromList("memtag_heap", globalSanitizersDiag); found &&
593*333d2b36SAndroid Build Coastguard Worker			s.Diag.Memtag_heap == nil && Bool(s.Memtag_heap) {
594*333d2b36SAndroid Build Coastguard Worker			s.Diag.Memtag_heap = proptools.BoolPtr(true)
595*333d2b36SAndroid Build Coastguard Worker		}
596*333d2b36SAndroid Build Coastguard Worker
597*333d2b36SAndroid Build Coastguard Worker		if len(globalSanitizersDiag) > 0 {
598*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("unknown global sanitizer diagnostics option %s", globalSanitizersDiag[0])
599*333d2b36SAndroid Build Coastguard Worker		}
600*333d2b36SAndroid Build Coastguard Worker	}
601*333d2b36SAndroid Build Coastguard Worker
602*333d2b36SAndroid Build Coastguard Worker	// Enable Memtag for all components in the include paths (for Aarch64 only)
603*333d2b36SAndroid Build Coastguard Worker	if ctx.Arch().ArchType == android.Arm64 && ctx.toolchain().Bionic() {
604*333d2b36SAndroid Build Coastguard Worker		if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) {
605*333d2b36SAndroid Build Coastguard Worker			if s.Memtag_heap == nil {
606*333d2b36SAndroid Build Coastguard Worker				s.Memtag_heap = proptools.BoolPtr(true)
607*333d2b36SAndroid Build Coastguard Worker			}
608*333d2b36SAndroid Build Coastguard Worker			if s.Diag.Memtag_heap == nil {
609*333d2b36SAndroid Build Coastguard Worker				s.Diag.Memtag_heap = proptools.BoolPtr(true)
610*333d2b36SAndroid Build Coastguard Worker			}
611*333d2b36SAndroid Build Coastguard Worker		} else if ctx.Config().MemtagHeapAsyncEnabledForPath(ctx.ModuleDir()) {
612*333d2b36SAndroid Build Coastguard Worker			if s.Memtag_heap == nil {
613*333d2b36SAndroid Build Coastguard Worker				s.Memtag_heap = proptools.BoolPtr(true)
614*333d2b36SAndroid Build Coastguard Worker			}
615*333d2b36SAndroid Build Coastguard Worker		}
616*333d2b36SAndroid Build Coastguard Worker	}
617*333d2b36SAndroid Build Coastguard Worker
618*333d2b36SAndroid Build Coastguard Worker	// Enable HWASan for all components in the include paths (for Aarch64 only)
619*333d2b36SAndroid Build Coastguard Worker	if s.Hwaddress == nil && ctx.Config().HWASanEnabledForPath(ctx.ModuleDir()) &&
620*333d2b36SAndroid Build Coastguard Worker		ctx.Arch().ArchType == android.Arm64 && ctx.toolchain().Bionic() {
621*333d2b36SAndroid Build Coastguard Worker		s.Hwaddress = proptools.BoolPtr(true)
622*333d2b36SAndroid Build Coastguard Worker	}
623*333d2b36SAndroid Build Coastguard Worker
624*333d2b36SAndroid Build Coastguard Worker	// Enable CFI for non-host components in the include paths
625*333d2b36SAndroid Build Coastguard Worker	if s.Cfi == nil && ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && !ctx.Host() {
626*333d2b36SAndroid Build Coastguard Worker		s.Cfi = proptools.BoolPtr(true)
627*333d2b36SAndroid Build Coastguard Worker		if inList("cfi", ctx.Config().SanitizeDeviceDiag()) {
628*333d2b36SAndroid Build Coastguard Worker			s.Diag.Cfi = proptools.BoolPtr(true)
629*333d2b36SAndroid Build Coastguard Worker		}
630*333d2b36SAndroid Build Coastguard Worker	}
631*333d2b36SAndroid Build Coastguard Worker
632*333d2b36SAndroid Build Coastguard Worker	// Is CFI actually enabled?
633*333d2b36SAndroid Build Coastguard Worker	if !ctx.Config().EnableCFI() {
634*333d2b36SAndroid Build Coastguard Worker		s.Cfi = nil
635*333d2b36SAndroid Build Coastguard Worker		s.Diag.Cfi = nil
636*333d2b36SAndroid Build Coastguard Worker	}
637*333d2b36SAndroid Build Coastguard Worker
638*333d2b36SAndroid Build Coastguard Worker	// HWASan requires AArch64 hardware feature (top-byte-ignore).
639*333d2b36SAndroid Build Coastguard Worker	if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() {
640*333d2b36SAndroid Build Coastguard Worker		s.Hwaddress = nil
641*333d2b36SAndroid Build Coastguard Worker	}
642*333d2b36SAndroid Build Coastguard Worker
643*333d2b36SAndroid Build Coastguard Worker	// SCS is only implemented on AArch64/riscv64.
644*333d2b36SAndroid Build Coastguard Worker	if (ctx.Arch().ArchType != android.Arm64 && ctx.Arch().ArchType != android.Riscv64) || !ctx.toolchain().Bionic() {
645*333d2b36SAndroid Build Coastguard Worker		s.Scs = nil
646*333d2b36SAndroid Build Coastguard Worker	}
647*333d2b36SAndroid Build Coastguard Worker
648*333d2b36SAndroid Build Coastguard Worker	// Memtag_heap is only implemented on AArch64.
649*333d2b36SAndroid Build Coastguard Worker	// Memtag ABI is Android specific for now, so disable for host.
650*333d2b36SAndroid Build Coastguard Worker	if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() || ctx.Host() {
651*333d2b36SAndroid Build Coastguard Worker		s.Memtag_heap = nil
652*333d2b36SAndroid Build Coastguard Worker		s.Memtag_stack = nil
653*333d2b36SAndroid Build Coastguard Worker		s.Memtag_globals = nil
654*333d2b36SAndroid Build Coastguard Worker	}
655*333d2b36SAndroid Build Coastguard Worker
656*333d2b36SAndroid Build Coastguard Worker	// Also disable CFI if ASAN is enabled.
657*333d2b36SAndroid Build Coastguard Worker	if Bool(s.Address) || Bool(s.Hwaddress) {
658*333d2b36SAndroid Build Coastguard Worker		s.Cfi = nil
659*333d2b36SAndroid Build Coastguard Worker		s.Diag.Cfi = nil
660*333d2b36SAndroid Build Coastguard Worker		// HWASAN and ASAN win against MTE.
661*333d2b36SAndroid Build Coastguard Worker		s.Memtag_heap = nil
662*333d2b36SAndroid Build Coastguard Worker		s.Memtag_stack = nil
663*333d2b36SAndroid Build Coastguard Worker		s.Memtag_globals = nil
664*333d2b36SAndroid Build Coastguard Worker	}
665*333d2b36SAndroid Build Coastguard Worker
666*333d2b36SAndroid Build Coastguard Worker	// Disable sanitizers that depend on the UBSan runtime for windows/darwin builds.
667*333d2b36SAndroid Build Coastguard Worker	if !ctx.Os().Linux() {
668*333d2b36SAndroid Build Coastguard Worker		s.Cfi = nil
669*333d2b36SAndroid Build Coastguard Worker		s.Diag.Cfi = nil
670*333d2b36SAndroid Build Coastguard Worker		s.Misc_undefined = nil
671*333d2b36SAndroid Build Coastguard Worker		s.Undefined = nil
672*333d2b36SAndroid Build Coastguard Worker		s.All_undefined = nil
673*333d2b36SAndroid Build Coastguard Worker		s.Integer_overflow = nil
674*333d2b36SAndroid Build Coastguard Worker	}
675*333d2b36SAndroid Build Coastguard Worker
676*333d2b36SAndroid Build Coastguard Worker	// Disable CFI for musl
677*333d2b36SAndroid Build Coastguard Worker	if ctx.toolchain().Musl() {
678*333d2b36SAndroid Build Coastguard Worker		s.Cfi = nil
679*333d2b36SAndroid Build Coastguard Worker		s.Diag.Cfi = nil
680*333d2b36SAndroid Build Coastguard Worker	}
681*333d2b36SAndroid Build Coastguard Worker
682*333d2b36SAndroid Build Coastguard Worker	// TODO(b/280478629): runtimes don't exist for musl arm64 yet.
683*333d2b36SAndroid Build Coastguard Worker	if ctx.toolchain().Musl() && ctx.Arch().ArchType == android.Arm64 {
684*333d2b36SAndroid Build Coastguard Worker		s.Address = nil
685*333d2b36SAndroid Build Coastguard Worker		s.Hwaddress = nil
686*333d2b36SAndroid Build Coastguard Worker		s.Thread = nil
687*333d2b36SAndroid Build Coastguard Worker		s.Scudo = nil
688*333d2b36SAndroid Build Coastguard Worker		s.Fuzzer = nil
689*333d2b36SAndroid Build Coastguard Worker		s.Cfi = nil
690*333d2b36SAndroid Build Coastguard Worker		s.Diag.Cfi = nil
691*333d2b36SAndroid Build Coastguard Worker		s.Misc_undefined = nil
692*333d2b36SAndroid Build Coastguard Worker		s.Undefined = nil
693*333d2b36SAndroid Build Coastguard Worker		s.All_undefined = nil
694*333d2b36SAndroid Build Coastguard Worker		s.Integer_overflow = nil
695*333d2b36SAndroid Build Coastguard Worker	}
696*333d2b36SAndroid Build Coastguard Worker
697*333d2b36SAndroid Build Coastguard Worker	if ctx.inRamdisk() || ctx.inVendorRamdisk() || ctx.inRecovery() {
698*333d2b36SAndroid Build Coastguard Worker		// HWASan ramdisk (which is built from recovery) goes over some bootloader limit.
699*333d2b36SAndroid Build Coastguard Worker		// Keep libc instrumented so that ramdisk / vendor_ramdisk / recovery can run hwasan-instrumented code if necessary.
700*333d2b36SAndroid Build Coastguard Worker		if !strings.HasPrefix(ctx.ModuleDir(), "bionic/libc") {
701*333d2b36SAndroid Build Coastguard Worker			s.Hwaddress = nil
702*333d2b36SAndroid Build Coastguard Worker		}
703*333d2b36SAndroid Build Coastguard Worker		// Memtag stack in ramdisk makes pKVM unhappy.
704*333d2b36SAndroid Build Coastguard Worker		s.Memtag_stack = nil
705*333d2b36SAndroid Build Coastguard Worker	}
706*333d2b36SAndroid Build Coastguard Worker
707*333d2b36SAndroid Build Coastguard Worker	if ctx.staticBinary() {
708*333d2b36SAndroid Build Coastguard Worker		s.Address = nil
709*333d2b36SAndroid Build Coastguard Worker		s.Fuzzer = nil
710*333d2b36SAndroid Build Coastguard Worker		s.Thread = nil
711*333d2b36SAndroid Build Coastguard Worker	}
712*333d2b36SAndroid Build Coastguard Worker
713*333d2b36SAndroid Build Coastguard Worker	if Bool(s.All_undefined) {
714*333d2b36SAndroid Build Coastguard Worker		s.Undefined = nil
715*333d2b36SAndroid Build Coastguard Worker	}
716*333d2b36SAndroid Build Coastguard Worker
717*333d2b36SAndroid Build Coastguard Worker	if !ctx.toolchain().Is64Bit() {
718*333d2b36SAndroid Build Coastguard Worker		// TSAN and SafeStack are not supported on 32-bit architectures
719*333d2b36SAndroid Build Coastguard Worker		s.Thread = nil
720*333d2b36SAndroid Build Coastguard Worker		s.Safestack = nil
721*333d2b36SAndroid Build Coastguard Worker		// TODO(ccross): error for compile_multilib = "32"?
722*333d2b36SAndroid Build Coastguard Worker	}
723*333d2b36SAndroid Build Coastguard Worker
724*333d2b36SAndroid Build Coastguard Worker	if ctx.Os() != android.Windows && (Bool(s.All_undefined) || Bool(s.Undefined) || Bool(s.Address) || Bool(s.Thread) ||
725*333d2b36SAndroid Build Coastguard Worker		Bool(s.Fuzzer) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0 ||
726*333d2b36SAndroid Build Coastguard Worker		Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs) || Bool(s.Memtag_heap) || Bool(s.Memtag_stack) ||
727*333d2b36SAndroid Build Coastguard Worker		Bool(s.Memtag_globals)) {
728*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizerEnabled = true
729*333d2b36SAndroid Build Coastguard Worker	}
730*333d2b36SAndroid Build Coastguard Worker
731*333d2b36SAndroid Build Coastguard Worker	// Disable Scudo if ASan or TSan is enabled, or if it's disabled globally.
732*333d2b36SAndroid Build Coastguard Worker	if Bool(s.Address) || Bool(s.Thread) || Bool(s.Hwaddress) || ctx.Config().DisableScudo() {
733*333d2b36SAndroid Build Coastguard Worker		s.Scudo = nil
734*333d2b36SAndroid Build Coastguard Worker	}
735*333d2b36SAndroid Build Coastguard Worker
736*333d2b36SAndroid Build Coastguard Worker	if Bool(s.Hwaddress) {
737*333d2b36SAndroid Build Coastguard Worker		s.Address = nil
738*333d2b36SAndroid Build Coastguard Worker		s.Thread = nil
739*333d2b36SAndroid Build Coastguard Worker	}
740*333d2b36SAndroid Build Coastguard Worker
741*333d2b36SAndroid Build Coastguard Worker	// TODO(b/131771163): CFI transiently depends on LTO, and thus Fuzzer is
742*333d2b36SAndroid Build Coastguard Worker	// mutually incompatible.
743*333d2b36SAndroid Build Coastguard Worker	if Bool(s.Fuzzer) {
744*333d2b36SAndroid Build Coastguard Worker		s.Cfi = nil
745*333d2b36SAndroid Build Coastguard Worker	}
746*333d2b36SAndroid Build Coastguard Worker}
747*333d2b36SAndroid Build Coastguard Worker
748*333d2b36SAndroid Build Coastguard Workerfunc toDisableImplicitIntegerChange(flags []string) bool {
749*333d2b36SAndroid Build Coastguard Worker	// Returns true if any flag is fsanitize*integer, and there is
750*333d2b36SAndroid Build Coastguard Worker	// no explicit flag about sanitize=implicit-integer-sign-change.
751*333d2b36SAndroid Build Coastguard Worker	for _, f := range flags {
752*333d2b36SAndroid Build Coastguard Worker		if strings.Contains(f, "sanitize=implicit-integer-sign-change") {
753*333d2b36SAndroid Build Coastguard Worker			return false
754*333d2b36SAndroid Build Coastguard Worker		}
755*333d2b36SAndroid Build Coastguard Worker	}
756*333d2b36SAndroid Build Coastguard Worker	for _, f := range flags {
757*333d2b36SAndroid Build Coastguard Worker		if strings.HasPrefix(f, "-fsanitize") && strings.Contains(f, "integer") {
758*333d2b36SAndroid Build Coastguard Worker			return true
759*333d2b36SAndroid Build Coastguard Worker		}
760*333d2b36SAndroid Build Coastguard Worker	}
761*333d2b36SAndroid Build Coastguard Worker	return false
762*333d2b36SAndroid Build Coastguard Worker}
763*333d2b36SAndroid Build Coastguard Worker
764*333d2b36SAndroid Build Coastguard Workerfunc toDisableUnsignedShiftBaseChange(flags []string) bool {
765*333d2b36SAndroid Build Coastguard Worker	// Returns true if any flag is fsanitize*integer, and there is
766*333d2b36SAndroid Build Coastguard Worker	// no explicit flag about sanitize=unsigned-shift-base.
767*333d2b36SAndroid Build Coastguard Worker	for _, f := range flags {
768*333d2b36SAndroid Build Coastguard Worker		if strings.Contains(f, "sanitize=unsigned-shift-base") {
769*333d2b36SAndroid Build Coastguard Worker			return false
770*333d2b36SAndroid Build Coastguard Worker		}
771*333d2b36SAndroid Build Coastguard Worker	}
772*333d2b36SAndroid Build Coastguard Worker	for _, f := range flags {
773*333d2b36SAndroid Build Coastguard Worker		if strings.HasPrefix(f, "-fsanitize") && strings.Contains(f, "integer") {
774*333d2b36SAndroid Build Coastguard Worker			return true
775*333d2b36SAndroid Build Coastguard Worker		}
776*333d2b36SAndroid Build Coastguard Worker	}
777*333d2b36SAndroid Build Coastguard Worker	return false
778*333d2b36SAndroid Build Coastguard Worker}
779*333d2b36SAndroid Build Coastguard Worker
780*333d2b36SAndroid Build Coastguard Workerfunc (s *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
781*333d2b36SAndroid Build Coastguard Worker	if s.Properties.ForceDisable {
782*333d2b36SAndroid Build Coastguard Worker		return flags
783*333d2b36SAndroid Build Coastguard Worker	}
784*333d2b36SAndroid Build Coastguard Worker
785*333d2b36SAndroid Build Coastguard Worker	if !s.Properties.SanitizerEnabled && !s.Properties.UbsanRuntimeDep {
786*333d2b36SAndroid Build Coastguard Worker		return flags
787*333d2b36SAndroid Build Coastguard Worker	}
788*333d2b36SAndroid Build Coastguard Worker	sanProps := &s.Properties.SanitizeMutated
789*333d2b36SAndroid Build Coastguard Worker
790*333d2b36SAndroid Build Coastguard Worker	if Bool(sanProps.Address) {
791*333d2b36SAndroid Build Coastguard Worker		if ctx.Arch().ArchType == android.Arm {
792*333d2b36SAndroid Build Coastguard Worker			// Frame pointer based unwinder in ASan requires ARM frame setup.
793*333d2b36SAndroid Build Coastguard Worker			// TODO: put in flags?
794*333d2b36SAndroid Build Coastguard Worker			flags.RequiredInstructionSet = "arm"
795*333d2b36SAndroid Build Coastguard Worker		}
796*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, asanCflags...)
797*333d2b36SAndroid Build Coastguard Worker
798*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Writeonly) {
799*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", "-asan-instrument-reads=0")
800*333d2b36SAndroid Build Coastguard Worker		}
801*333d2b36SAndroid Build Coastguard Worker
802*333d2b36SAndroid Build Coastguard Worker		if ctx.Host() {
803*333d2b36SAndroid Build Coastguard Worker			if !ctx.Darwin() { // ld64.lld doesn't know about '--no-as-needed'
804*333d2b36SAndroid Build Coastguard Worker				// -nodefaultlibs (provided with libc++) prevents the driver from linking
805*333d2b36SAndroid Build Coastguard Worker				// libraries needed with -fsanitize=address. http://b/18650275 (WAI)
806*333d2b36SAndroid Build Coastguard Worker				flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--no-as-needed")
807*333d2b36SAndroid Build Coastguard Worker			}
808*333d2b36SAndroid Build Coastguard Worker		} else {
809*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", "-asan-globals=0")
810*333d2b36SAndroid Build Coastguard Worker			if ctx.bootstrap() {
811*333d2b36SAndroid Build Coastguard Worker				flags.DynamicLinker = "/system/bin/bootstrap/linker_asan"
812*333d2b36SAndroid Build Coastguard Worker			} else {
813*333d2b36SAndroid Build Coastguard Worker				flags.DynamicLinker = "/system/bin/linker_asan"
814*333d2b36SAndroid Build Coastguard Worker			}
815*333d2b36SAndroid Build Coastguard Worker			if flags.Toolchain.Is64Bit() {
816*333d2b36SAndroid Build Coastguard Worker				flags.DynamicLinker += "64"
817*333d2b36SAndroid Build Coastguard Worker			}
818*333d2b36SAndroid Build Coastguard Worker		}
819*333d2b36SAndroid Build Coastguard Worker	}
820*333d2b36SAndroid Build Coastguard Worker
821*333d2b36SAndroid Build Coastguard Worker	if Bool(sanProps.Hwaddress) {
822*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, hwasanCflags...)
823*333d2b36SAndroid Build Coastguard Worker
824*333d2b36SAndroid Build Coastguard Worker		for _, flag := range hwasanCommonflags {
825*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", flag)
826*333d2b36SAndroid Build Coastguard Worker		}
827*333d2b36SAndroid Build Coastguard Worker		for _, flag := range hwasanCommonflags {
828*333d2b36SAndroid Build Coastguard Worker			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,"+flag)
829*333d2b36SAndroid Build Coastguard Worker		}
830*333d2b36SAndroid Build Coastguard Worker
831*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Writeonly) {
832*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", "-hwasan-instrument-reads=0")
833*333d2b36SAndroid Build Coastguard Worker		}
834*333d2b36SAndroid Build Coastguard Worker		if !ctx.staticBinary() && !ctx.Host() {
835*333d2b36SAndroid Build Coastguard Worker			if ctx.bootstrap() {
836*333d2b36SAndroid Build Coastguard Worker				flags.DynamicLinker = "/system/bin/bootstrap/linker_hwasan64"
837*333d2b36SAndroid Build Coastguard Worker			} else {
838*333d2b36SAndroid Build Coastguard Worker				flags.DynamicLinker = "/system/bin/linker_hwasan64"
839*333d2b36SAndroid Build Coastguard Worker			}
840*333d2b36SAndroid Build Coastguard Worker		}
841*333d2b36SAndroid Build Coastguard Worker	}
842*333d2b36SAndroid Build Coastguard Worker
843*333d2b36SAndroid Build Coastguard Worker	if Bool(sanProps.Fuzzer) {
844*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize=fuzzer-no-link")
845*333d2b36SAndroid Build Coastguard Worker
846*333d2b36SAndroid Build Coastguard Worker		// TODO(b/131771163): LTO and Fuzzer support is mutually incompatible.
847*333d2b36SAndroid Build Coastguard Worker		_, flags.Local.LdFlags = removeFromList("-flto", flags.Local.LdFlags)
848*333d2b36SAndroid Build Coastguard Worker		_, flags.Local.CFlags = removeFromList("-flto", flags.Local.CFlags)
849*333d2b36SAndroid Build Coastguard Worker		flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-lto")
850*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, "-fno-lto")
851*333d2b36SAndroid Build Coastguard Worker
852*333d2b36SAndroid Build Coastguard Worker		// TODO(b/142430592): Upstream linker scripts for sanitizer runtime libraries
853*333d2b36SAndroid Build Coastguard Worker		// discard the sancov_lowest_stack symbol, because it's emulated TLS (and thus
854*333d2b36SAndroid Build Coastguard Worker		// doesn't match the linker script due to the "__emutls_v." prefix).
855*333d2b36SAndroid Build Coastguard Worker		flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-sanitize-coverage=stack-depth")
856*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-coverage=stack-depth")
857*333d2b36SAndroid Build Coastguard Worker
858*333d2b36SAndroid Build Coastguard Worker		// Disable fortify for fuzzing builds. Generally, we'll be building with
859*333d2b36SAndroid Build Coastguard Worker		// UBSan or ASan here and the fortify checks pollute the stack traces.
860*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, "-U_FORTIFY_SOURCE")
861*333d2b36SAndroid Build Coastguard Worker
862*333d2b36SAndroid Build Coastguard Worker		// Build fuzzer-sanitized libraries with an $ORIGIN DT_RUNPATH. Android's
863*333d2b36SAndroid Build Coastguard Worker		// linker uses DT_RUNPATH, not DT_RPATH. When we deploy cc_fuzz targets and
864*333d2b36SAndroid Build Coastguard Worker		// their libraries to /data/fuzz/<arch>/lib, any transient shared library gets
865*333d2b36SAndroid Build Coastguard Worker		// the DT_RUNPATH from the shared library above it, and not the executable,
866*333d2b36SAndroid Build Coastguard Worker		// meaning that the lookup falls back to the system. Adding the $ORIGIN to the
867*333d2b36SAndroid Build Coastguard Worker		// DT_RUNPATH here means that transient shared libraries can be found
868*333d2b36SAndroid Build Coastguard Worker		// colocated with their parents.
869*333d2b36SAndroid Build Coastguard Worker		flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN`)
870*333d2b36SAndroid Build Coastguard Worker	}
871*333d2b36SAndroid Build Coastguard Worker
872*333d2b36SAndroid Build Coastguard Worker	if Bool(sanProps.Cfi) {
873*333d2b36SAndroid Build Coastguard Worker		if ctx.Arch().ArchType == android.Arm {
874*333d2b36SAndroid Build Coastguard Worker			// __cfi_check needs to be built as Thumb (see the code in linker_cfi.cpp). LLVM is not set up
875*333d2b36SAndroid Build Coastguard Worker			// to do this on a function basis, so force Thumb on the entire module.
876*333d2b36SAndroid Build Coastguard Worker			flags.RequiredInstructionSet = "thumb"
877*333d2b36SAndroid Build Coastguard Worker		}
878*333d2b36SAndroid Build Coastguard Worker
879*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, cfiCflags...)
880*333d2b36SAndroid Build Coastguard Worker		flags.Local.AsFlags = append(flags.Local.AsFlags, cfiAsflags...)
881*333d2b36SAndroid Build Coastguard Worker		flags.CFlagsDeps = append(flags.CFlagsDeps, android.PathForSource(ctx, cfiBlocklistPath+"/"+cfiBlocklistFilename))
882*333d2b36SAndroid Build Coastguard Worker		if Bool(s.Properties.Sanitize.Config.Cfi_assembly_support) {
883*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, cfiAssemblySupportFlag)
884*333d2b36SAndroid Build Coastguard Worker		}
885*333d2b36SAndroid Build Coastguard Worker		// Only append the default visibility flag if -fvisibility has not already been set
886*333d2b36SAndroid Build Coastguard Worker		// to hidden.
887*333d2b36SAndroid Build Coastguard Worker		if !inList("-fvisibility=hidden", flags.Local.CFlags) {
888*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, "-fvisibility=default")
889*333d2b36SAndroid Build Coastguard Worker		}
890*333d2b36SAndroid Build Coastguard Worker		flags.Local.LdFlags = append(flags.Local.LdFlags, cfiLdflags...)
891*333d2b36SAndroid Build Coastguard Worker
892*333d2b36SAndroid Build Coastguard Worker		if ctx.staticBinary() {
893*333d2b36SAndroid Build Coastguard Worker			_, flags.Local.CFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.Local.CFlags)
894*333d2b36SAndroid Build Coastguard Worker			_, flags.Local.LdFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.Local.LdFlags)
895*333d2b36SAndroid Build Coastguard Worker		}
896*333d2b36SAndroid Build Coastguard Worker	}
897*333d2b36SAndroid Build Coastguard Worker
898*333d2b36SAndroid Build Coastguard Worker	if Bool(sanProps.Memtag_stack) {
899*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, memtagStackCommonFlags...)
900*333d2b36SAndroid Build Coastguard Worker		flags.Local.AsFlags = append(flags.Local.AsFlags, memtagStackCommonFlags...)
901*333d2b36SAndroid Build Coastguard Worker		flags.Local.LdFlags = append(flags.Local.LdFlags, memtagStackCommonFlags...)
902*333d2b36SAndroid Build Coastguard Worker
903*333d2b36SAndroid Build Coastguard Worker		for _, flag := range memtagStackLlvmFlags {
904*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", flag)
905*333d2b36SAndroid Build Coastguard Worker		}
906*333d2b36SAndroid Build Coastguard Worker		for _, flag := range memtagStackLlvmFlags {
907*333d2b36SAndroid Build Coastguard Worker			flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,"+flag)
908*333d2b36SAndroid Build Coastguard Worker		}
909*333d2b36SAndroid Build Coastguard Worker	}
910*333d2b36SAndroid Build Coastguard Worker
911*333d2b36SAndroid Build Coastguard Worker	if (Bool(sanProps.Memtag_heap) || Bool(sanProps.Memtag_stack) || Bool(sanProps.Memtag_globals)) && ctx.binary() {
912*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Diag.Memtag_heap) {
913*333d2b36SAndroid Build Coastguard Worker			flags.Local.LdFlags = append(flags.Local.LdFlags, "-fsanitize-memtag-mode=sync")
914*333d2b36SAndroid Build Coastguard Worker		} else {
915*333d2b36SAndroid Build Coastguard Worker			flags.Local.LdFlags = append(flags.Local.LdFlags, "-fsanitize-memtag-mode=async")
916*333d2b36SAndroid Build Coastguard Worker		}
917*333d2b36SAndroid Build Coastguard Worker	}
918*333d2b36SAndroid Build Coastguard Worker
919*333d2b36SAndroid Build Coastguard Worker	if Bool(sanProps.Integer_overflow) {
920*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, intOverflowCflags...)
921*333d2b36SAndroid Build Coastguard Worker	}
922*333d2b36SAndroid Build Coastguard Worker
923*333d2b36SAndroid Build Coastguard Worker	if len(s.Properties.Sanitizers) > 0 {
924*333d2b36SAndroid Build Coastguard Worker		sanitizeArg := "-fsanitize=" + strings.Join(s.Properties.Sanitizers, ",")
925*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, sanitizeArg)
926*333d2b36SAndroid Build Coastguard Worker		flags.Local.AsFlags = append(flags.Local.AsFlags, sanitizeArg)
927*333d2b36SAndroid Build Coastguard Worker		flags.Local.LdFlags = append(flags.Local.LdFlags, sanitizeArg)
928*333d2b36SAndroid Build Coastguard Worker
929*333d2b36SAndroid Build Coastguard Worker		if ctx.toolchain().Bionic() || ctx.toolchain().Musl() {
930*333d2b36SAndroid Build Coastguard Worker			// Bionic and musl sanitizer runtimes have already been added as dependencies so that
931*333d2b36SAndroid Build Coastguard Worker			// the right variant of the runtime will be used (with the "-android" or "-musl"
932*333d2b36SAndroid Build Coastguard Worker			// suffixes), so don't let clang the runtime library.
933*333d2b36SAndroid Build Coastguard Worker			flags.Local.LdFlags = append(flags.Local.LdFlags, noSanitizeLinkRuntimeFlag)
934*333d2b36SAndroid Build Coastguard Worker		} else {
935*333d2b36SAndroid Build Coastguard Worker			// Host sanitizers only link symbols in the final executable, so
936*333d2b36SAndroid Build Coastguard Worker			// there will always be undefined symbols in intermediate libraries.
937*333d2b36SAndroid Build Coastguard Worker			_, flags.Global.LdFlags = removeFromList("-Wl,--no-undefined", flags.Global.LdFlags)
938*333d2b36SAndroid Build Coastguard Worker		}
939*333d2b36SAndroid Build Coastguard Worker
940*333d2b36SAndroid Build Coastguard Worker		if !ctx.toolchain().Bionic() {
941*333d2b36SAndroid Build Coastguard Worker			// non-Bionic toolchain prebuilts are missing UBSan's vptr and function san.
942*333d2b36SAndroid Build Coastguard Worker			// Musl toolchain prebuilts have vptr and function sanitizers, but enabling them
943*333d2b36SAndroid Build Coastguard Worker			// implicitly enables RTTI which causes RTTI mismatch issues with dependencies.
944*333d2b36SAndroid Build Coastguard Worker
945*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize=vptr,function")
946*333d2b36SAndroid Build Coastguard Worker		}
947*333d2b36SAndroid Build Coastguard Worker
948*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Fuzzer) {
949*333d2b36SAndroid Build Coastguard Worker			// When fuzzing, we wish to crash with diagnostics on any bug.
950*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-trap=all", "-fno-sanitize-recover=all")
951*333d2b36SAndroid Build Coastguard Worker		} else if ctx.Host() {
952*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, hostOnlySanitizeFlags...)
953*333d2b36SAndroid Build Coastguard Worker		} else {
954*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, deviceOnlySanitizeFlags...)
955*333d2b36SAndroid Build Coastguard Worker		}
956*333d2b36SAndroid Build Coastguard Worker
957*333d2b36SAndroid Build Coastguard Worker		if enableMinimalRuntime(s) {
958*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, strings.Join(minimalRuntimeFlags, " "))
959*333d2b36SAndroid Build Coastguard Worker		}
960*333d2b36SAndroid Build Coastguard Worker
961*333d2b36SAndroid Build Coastguard Worker		// http://b/119329758, Android core does not boot up with this sanitizer yet.
962*333d2b36SAndroid Build Coastguard Worker		if toDisableImplicitIntegerChange(flags.Local.CFlags) {
963*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize=implicit-integer-sign-change")
964*333d2b36SAndroid Build Coastguard Worker		}
965*333d2b36SAndroid Build Coastguard Worker		// http://b/171275751, Android doesn't build with this sanitizer yet.
966*333d2b36SAndroid Build Coastguard Worker		if toDisableUnsignedShiftBaseChange(flags.Local.CFlags) {
967*333d2b36SAndroid Build Coastguard Worker			flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize=unsigned-shift-base")
968*333d2b36SAndroid Build Coastguard Worker		}
969*333d2b36SAndroid Build Coastguard Worker	}
970*333d2b36SAndroid Build Coastguard Worker
971*333d2b36SAndroid Build Coastguard Worker	if len(s.Properties.DiagSanitizers) > 0 {
972*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-trap="+strings.Join(s.Properties.DiagSanitizers, ","))
973*333d2b36SAndroid Build Coastguard Worker	}
974*333d2b36SAndroid Build Coastguard Worker	// FIXME: enable RTTI if diag + (cfi or vptr)
975*333d2b36SAndroid Build Coastguard Worker
976*333d2b36SAndroid Build Coastguard Worker	if s.Properties.Sanitize.Recover != nil {
977*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-recover="+
978*333d2b36SAndroid Build Coastguard Worker			strings.Join(s.Properties.Sanitize.Recover, ","))
979*333d2b36SAndroid Build Coastguard Worker	}
980*333d2b36SAndroid Build Coastguard Worker
981*333d2b36SAndroid Build Coastguard Worker	if s.Properties.Sanitize.Diag.No_recover != nil {
982*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-recover="+
983*333d2b36SAndroid Build Coastguard Worker			strings.Join(s.Properties.Sanitize.Diag.No_recover, ","))
984*333d2b36SAndroid Build Coastguard Worker	}
985*333d2b36SAndroid Build Coastguard Worker
986*333d2b36SAndroid Build Coastguard Worker	blocklist := android.OptionalPathForModuleSrc(ctx, s.Properties.Sanitize.Blocklist)
987*333d2b36SAndroid Build Coastguard Worker	if blocklist.Valid() {
988*333d2b36SAndroid Build Coastguard Worker		flags.Local.CFlags = append(flags.Local.CFlags, sanitizeIgnorelistPrefix+blocklist.String())
989*333d2b36SAndroid Build Coastguard Worker		flags.CFlagsDeps = append(flags.CFlagsDeps, blocklist.Path())
990*333d2b36SAndroid Build Coastguard Worker	}
991*333d2b36SAndroid Build Coastguard Worker
992*333d2b36SAndroid Build Coastguard Worker	return flags
993*333d2b36SAndroid Build Coastguard Worker}
994*333d2b36SAndroid Build Coastguard Worker
995*333d2b36SAndroid Build Coastguard Workerfunc (s *sanitize) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
996*333d2b36SAndroid Build Coastguard Worker	// Add a suffix for cfi/hwasan/scs-enabled static/header libraries to allow surfacing
997*333d2b36SAndroid Build Coastguard Worker	// both the sanitized and non-sanitized variants to make without a name conflict.
998*333d2b36SAndroid Build Coastguard Worker	if entries.Class == "STATIC_LIBRARIES" || entries.Class == "HEADER_LIBRARIES" {
999*333d2b36SAndroid Build Coastguard Worker		if Bool(s.Properties.SanitizeMutated.Cfi) {
1000*333d2b36SAndroid Build Coastguard Worker			entries.SubName += ".cfi"
1001*333d2b36SAndroid Build Coastguard Worker		}
1002*333d2b36SAndroid Build Coastguard Worker		if Bool(s.Properties.SanitizeMutated.Hwaddress) {
1003*333d2b36SAndroid Build Coastguard Worker			entries.SubName += ".hwasan"
1004*333d2b36SAndroid Build Coastguard Worker		}
1005*333d2b36SAndroid Build Coastguard Worker		if Bool(s.Properties.SanitizeMutated.Scs) {
1006*333d2b36SAndroid Build Coastguard Worker			entries.SubName += ".scs"
1007*333d2b36SAndroid Build Coastguard Worker		}
1008*333d2b36SAndroid Build Coastguard Worker	}
1009*333d2b36SAndroid Build Coastguard Worker}
1010*333d2b36SAndroid Build Coastguard Worker
1011*333d2b36SAndroid Build Coastguard Workerfunc (s *sanitize) inSanitizerDir() bool {
1012*333d2b36SAndroid Build Coastguard Worker	return s.Properties.InSanitizerDir
1013*333d2b36SAndroid Build Coastguard Worker}
1014*333d2b36SAndroid Build Coastguard Worker
1015*333d2b36SAndroid Build Coastguard Worker// getSanitizerBoolPtr returns the SanitizerTypes associated bool pointer from SanitizeProperties.
1016*333d2b36SAndroid Build Coastguard Workerfunc (s *sanitize) getSanitizerBoolPtr(t SanitizerType) *bool {
1017*333d2b36SAndroid Build Coastguard Worker	switch t {
1018*333d2b36SAndroid Build Coastguard Worker	case Asan:
1019*333d2b36SAndroid Build Coastguard Worker		return s.Properties.SanitizeMutated.Address
1020*333d2b36SAndroid Build Coastguard Worker	case Hwasan:
1021*333d2b36SAndroid Build Coastguard Worker		return s.Properties.SanitizeMutated.Hwaddress
1022*333d2b36SAndroid Build Coastguard Worker	case tsan:
1023*333d2b36SAndroid Build Coastguard Worker		return s.Properties.SanitizeMutated.Thread
1024*333d2b36SAndroid Build Coastguard Worker	case intOverflow:
1025*333d2b36SAndroid Build Coastguard Worker		return s.Properties.SanitizeMutated.Integer_overflow
1026*333d2b36SAndroid Build Coastguard Worker	case cfi:
1027*333d2b36SAndroid Build Coastguard Worker		return s.Properties.SanitizeMutated.Cfi
1028*333d2b36SAndroid Build Coastguard Worker	case scs:
1029*333d2b36SAndroid Build Coastguard Worker		return s.Properties.SanitizeMutated.Scs
1030*333d2b36SAndroid Build Coastguard Worker	case Memtag_heap:
1031*333d2b36SAndroid Build Coastguard Worker		return s.Properties.SanitizeMutated.Memtag_heap
1032*333d2b36SAndroid Build Coastguard Worker	case Memtag_stack:
1033*333d2b36SAndroid Build Coastguard Worker		return s.Properties.SanitizeMutated.Memtag_stack
1034*333d2b36SAndroid Build Coastguard Worker	case Memtag_globals:
1035*333d2b36SAndroid Build Coastguard Worker		return s.Properties.SanitizeMutated.Memtag_globals
1036*333d2b36SAndroid Build Coastguard Worker	case Fuzzer:
1037*333d2b36SAndroid Build Coastguard Worker		return s.Properties.SanitizeMutated.Fuzzer
1038*333d2b36SAndroid Build Coastguard Worker	default:
1039*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("unknown SanitizerType %d", t))
1040*333d2b36SAndroid Build Coastguard Worker	}
1041*333d2b36SAndroid Build Coastguard Worker}
1042*333d2b36SAndroid Build Coastguard Worker
1043*333d2b36SAndroid Build Coastguard Worker// isUnsanitizedVariant returns true if no sanitizers are enabled.
1044*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) isUnsanitizedVariant() bool {
1045*333d2b36SAndroid Build Coastguard Worker	return !sanitize.isSanitizerEnabled(Asan) &&
1046*333d2b36SAndroid Build Coastguard Worker		!sanitize.isSanitizerEnabled(Hwasan) &&
1047*333d2b36SAndroid Build Coastguard Worker		!sanitize.isSanitizerEnabled(tsan) &&
1048*333d2b36SAndroid Build Coastguard Worker		!sanitize.isSanitizerEnabled(cfi) &&
1049*333d2b36SAndroid Build Coastguard Worker		!sanitize.isSanitizerEnabled(scs) &&
1050*333d2b36SAndroid Build Coastguard Worker		!sanitize.isSanitizerEnabled(Memtag_heap) &&
1051*333d2b36SAndroid Build Coastguard Worker		!sanitize.isSanitizerEnabled(Memtag_stack) &&
1052*333d2b36SAndroid Build Coastguard Worker		!sanitize.isSanitizerEnabled(Memtag_globals) &&
1053*333d2b36SAndroid Build Coastguard Worker		!sanitize.isSanitizerEnabled(Fuzzer)
1054*333d2b36SAndroid Build Coastguard Worker}
1055*333d2b36SAndroid Build Coastguard Worker
1056*333d2b36SAndroid Build Coastguard Worker// isVariantOnProductionDevice returns true if variant is for production devices (no non-production sanitizers enabled).
1057*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) isVariantOnProductionDevice() bool {
1058*333d2b36SAndroid Build Coastguard Worker	return !sanitize.isSanitizerEnabled(Asan) &&
1059*333d2b36SAndroid Build Coastguard Worker		!sanitize.isSanitizerEnabled(Hwasan) &&
1060*333d2b36SAndroid Build Coastguard Worker		!sanitize.isSanitizerEnabled(tsan) &&
1061*333d2b36SAndroid Build Coastguard Worker		!sanitize.isSanitizerEnabled(Fuzzer)
1062*333d2b36SAndroid Build Coastguard Worker}
1063*333d2b36SAndroid Build Coastguard Worker
1064*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) SetSanitizer(t SanitizerType, b bool) {
1065*333d2b36SAndroid Build Coastguard Worker	bPtr := proptools.BoolPtr(b)
1066*333d2b36SAndroid Build Coastguard Worker	if !b {
1067*333d2b36SAndroid Build Coastguard Worker		bPtr = nil
1068*333d2b36SAndroid Build Coastguard Worker	}
1069*333d2b36SAndroid Build Coastguard Worker	switch t {
1070*333d2b36SAndroid Build Coastguard Worker	case Asan:
1071*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizeMutated.Address = bPtr
1072*333d2b36SAndroid Build Coastguard Worker		// For ASAN variant, we need to disable Memtag_stack
1073*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizeMutated.Memtag_stack = nil
1074*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizeMutated.Memtag_globals = nil
1075*333d2b36SAndroid Build Coastguard Worker	case Hwasan:
1076*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizeMutated.Hwaddress = bPtr
1077*333d2b36SAndroid Build Coastguard Worker		// For HWAsan variant, we need to disable Memtag_stack
1078*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizeMutated.Memtag_stack = nil
1079*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizeMutated.Memtag_globals = nil
1080*333d2b36SAndroid Build Coastguard Worker	case tsan:
1081*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizeMutated.Thread = bPtr
1082*333d2b36SAndroid Build Coastguard Worker	case intOverflow:
1083*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizeMutated.Integer_overflow = bPtr
1084*333d2b36SAndroid Build Coastguard Worker	case cfi:
1085*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizeMutated.Cfi = bPtr
1086*333d2b36SAndroid Build Coastguard Worker	case scs:
1087*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizeMutated.Scs = bPtr
1088*333d2b36SAndroid Build Coastguard Worker	case Memtag_heap:
1089*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizeMutated.Memtag_heap = bPtr
1090*333d2b36SAndroid Build Coastguard Worker	case Memtag_stack:
1091*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizeMutated.Memtag_stack = bPtr
1092*333d2b36SAndroid Build Coastguard Worker		// We do not need to disable ASAN or HWASan here, as there is no Memtag_stack variant.
1093*333d2b36SAndroid Build Coastguard Worker	case Memtag_globals:
1094*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.Sanitize.Memtag_globals = bPtr
1095*333d2b36SAndroid Build Coastguard Worker	case Fuzzer:
1096*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizeMutated.Fuzzer = bPtr
1097*333d2b36SAndroid Build Coastguard Worker	default:
1098*333d2b36SAndroid Build Coastguard Worker		panic(fmt.Errorf("unknown SanitizerType %d", t))
1099*333d2b36SAndroid Build Coastguard Worker	}
1100*333d2b36SAndroid Build Coastguard Worker	if b {
1101*333d2b36SAndroid Build Coastguard Worker		sanitize.Properties.SanitizerEnabled = true
1102*333d2b36SAndroid Build Coastguard Worker	}
1103*333d2b36SAndroid Build Coastguard Worker}
1104*333d2b36SAndroid Build Coastguard Worker
1105*333d2b36SAndroid Build Coastguard Worker// Check if the sanitizer is explicitly disabled (as opposed to nil by
1106*333d2b36SAndroid Build Coastguard Worker// virtue of not being set).
1107*333d2b36SAndroid Build Coastguard Workerfunc (sanitize *sanitize) isSanitizerExplicitlyDisabled(t SanitizerType) bool {
1108*333d2b36SAndroid Build Coastguard Worker	if sanitize == nil {
1109*333d2b36SAndroid Build Coastguard Worker		return false
1110*333d2b36SAndroid Build Coastguard Worker	}
1111*333d2b36SAndroid Build Coastguard Worker
1112*333d2b36SAndroid Build Coastguard Worker	sanitizerVal := sanitize.getSanitizerBoolPtr(t)
1113*333d2b36SAndroid Build Coastguard Worker	return sanitizerVal != nil && *sanitizerVal == false
1114*333d2b36SAndroid Build Coastguard Worker}
1115*333d2b36SAndroid Build Coastguard Worker
1116*333d2b36SAndroid Build Coastguard Worker// There isn't an analog of the method above (ie:isSanitizerExplicitlyEnabled)
1117*333d2b36SAndroid Build Coastguard Worker// because enabling a sanitizer either directly (via the blueprint) or
1118*333d2b36SAndroid Build Coastguard Worker// indirectly (via a mutator) sets the bool ptr to true, and you can't
1119*333d2b36SAndroid Build Coastguard Worker// distinguish between the cases. It isn't needed though - both cases can be
1120*333d2b36SAndroid Build Coastguard Worker// treated identically.
1121*333d2b36SAndroid Build Coastguard Workerfunc (s *sanitize) isSanitizerEnabled(t SanitizerType) bool {
1122*333d2b36SAndroid Build Coastguard Worker	if s == nil {
1123*333d2b36SAndroid Build Coastguard Worker		return false
1124*333d2b36SAndroid Build Coastguard Worker	}
1125*333d2b36SAndroid Build Coastguard Worker	if s.Properties.ForceDisable || proptools.Bool(s.Properties.SanitizeMutated.Never) {
1126*333d2b36SAndroid Build Coastguard Worker		return false
1127*333d2b36SAndroid Build Coastguard Worker	}
1128*333d2b36SAndroid Build Coastguard Worker
1129*333d2b36SAndroid Build Coastguard Worker	sanitizerVal := s.getSanitizerBoolPtr(t)
1130*333d2b36SAndroid Build Coastguard Worker	return sanitizerVal != nil && *sanitizerVal == true
1131*333d2b36SAndroid Build Coastguard Worker}
1132*333d2b36SAndroid Build Coastguard Worker
1133*333d2b36SAndroid Build Coastguard Worker// IsSanitizableDependencyTag returns true if the dependency tag is sanitizable.
1134*333d2b36SAndroid Build Coastguard Workerfunc IsSanitizableDependencyTag(tag blueprint.DependencyTag) bool {
1135*333d2b36SAndroid Build Coastguard Worker	switch t := tag.(type) {
1136*333d2b36SAndroid Build Coastguard Worker	case dependencyTag:
1137*333d2b36SAndroid Build Coastguard Worker		return t == reuseObjTag || t == objDepTag
1138*333d2b36SAndroid Build Coastguard Worker	case libraryDependencyTag:
1139*333d2b36SAndroid Build Coastguard Worker		return true
1140*333d2b36SAndroid Build Coastguard Worker	default:
1141*333d2b36SAndroid Build Coastguard Worker		return false
1142*333d2b36SAndroid Build Coastguard Worker	}
1143*333d2b36SAndroid Build Coastguard Worker}
1144*333d2b36SAndroid Build Coastguard Worker
1145*333d2b36SAndroid Build Coastguard Workerfunc (m *Module) SanitizableDepTagChecker() SantizableDependencyTagChecker {
1146*333d2b36SAndroid Build Coastguard Worker	return IsSanitizableDependencyTag
1147*333d2b36SAndroid Build Coastguard Worker}
1148*333d2b36SAndroid Build Coastguard Worker
1149*333d2b36SAndroid Build Coastguard Workertype sanitizerSplitMutator struct {
1150*333d2b36SAndroid Build Coastguard Worker	sanitizer SanitizerType
1151*333d2b36SAndroid Build Coastguard Worker}
1152*333d2b36SAndroid Build Coastguard Worker
1153*333d2b36SAndroid Build Coastguard Worker// If an APEX is sanitized or not depends on whether it contains at least one
1154*333d2b36SAndroid Build Coastguard Worker// sanitized module. Transition mutators cannot propagate information up the
1155*333d2b36SAndroid Build Coastguard Worker// dependency graph this way, so we need an auxiliary mutator to do so.
1156*333d2b36SAndroid Build Coastguard Workerfunc (s *sanitizerSplitMutator) markSanitizableApexesMutator(ctx android.BottomUpMutatorContext) {
1157*333d2b36SAndroid Build Coastguard Worker	if sanitizeable, ok := ctx.Module().(Sanitizeable); ok {
1158*333d2b36SAndroid Build Coastguard Worker		enabled := sanitizeable.IsSanitizerEnabled(ctx.Config(), s.sanitizer.name())
1159*333d2b36SAndroid Build Coastguard Worker		ctx.VisitDirectDeps(func(dep android.Module) {
1160*333d2b36SAndroid Build Coastguard Worker			if c, ok := dep.(PlatformSanitizeable); ok && c.IsSanitizerEnabled(s.sanitizer) {
1161*333d2b36SAndroid Build Coastguard Worker				enabled = true
1162*333d2b36SAndroid Build Coastguard Worker			}
1163*333d2b36SAndroid Build Coastguard Worker		})
1164*333d2b36SAndroid Build Coastguard Worker
1165*333d2b36SAndroid Build Coastguard Worker		if enabled {
1166*333d2b36SAndroid Build Coastguard Worker			sanitizeable.EnableSanitizer(s.sanitizer.name())
1167*333d2b36SAndroid Build Coastguard Worker		}
1168*333d2b36SAndroid Build Coastguard Worker	}
1169*333d2b36SAndroid Build Coastguard Worker}
1170*333d2b36SAndroid Build Coastguard Worker
1171*333d2b36SAndroid Build Coastguard Workerfunc (s *sanitizerSplitMutator) Split(ctx android.BaseModuleContext) []string {
1172*333d2b36SAndroid Build Coastguard Worker	if c, ok := ctx.Module().(PlatformSanitizeable); ok && c.SanitizePropDefined() {
1173*333d2b36SAndroid Build Coastguard Worker		// If the given sanitizer is not requested in the .bp file for a module, it
1174*333d2b36SAndroid Build Coastguard Worker		// won't automatically build the sanitized variation.
1175*333d2b36SAndroid Build Coastguard Worker		if !c.IsSanitizerEnabled(s.sanitizer) {
1176*333d2b36SAndroid Build Coastguard Worker			return []string{""}
1177*333d2b36SAndroid Build Coastguard Worker		}
1178*333d2b36SAndroid Build Coastguard Worker
1179*333d2b36SAndroid Build Coastguard Worker		if c.Binary() {
1180*333d2b36SAndroid Build Coastguard Worker			// If a sanitizer is enabled for a binary, we do not build the version
1181*333d2b36SAndroid Build Coastguard Worker			// without the sanitizer
1182*333d2b36SAndroid Build Coastguard Worker			return []string{s.sanitizer.variationName()}
1183*333d2b36SAndroid Build Coastguard Worker		} else if c.StaticallyLinked() || c.Header() {
1184*333d2b36SAndroid Build Coastguard Worker			// For static libraries, we build both versions. Some Make modules
1185*333d2b36SAndroid Build Coastguard Worker			// apparently depend on this behavior.
1186*333d2b36SAndroid Build Coastguard Worker			return []string{"", s.sanitizer.variationName()}
1187*333d2b36SAndroid Build Coastguard Worker		} else {
1188*333d2b36SAndroid Build Coastguard Worker			// We only build the requested variation of dynamic libraries
1189*333d2b36SAndroid Build Coastguard Worker			return []string{s.sanitizer.variationName()}
1190*333d2b36SAndroid Build Coastguard Worker		}
1191*333d2b36SAndroid Build Coastguard Worker	}
1192*333d2b36SAndroid Build Coastguard Worker
1193*333d2b36SAndroid Build Coastguard Worker	if _, ok := ctx.Module().(JniSanitizeable); ok {
1194*333d2b36SAndroid Build Coastguard Worker		// TODO: this should call into JniSanitizable.IsSanitizerEnabledForJni but
1195*333d2b36SAndroid Build Coastguard Worker		// that is short-circuited for now
1196*333d2b36SAndroid Build Coastguard Worker		return []string{""}
1197*333d2b36SAndroid Build Coastguard Worker	}
1198*333d2b36SAndroid Build Coastguard Worker
1199*333d2b36SAndroid Build Coastguard Worker	// If an APEX has a sanitized dependency, we build the APEX in the sanitized
1200*333d2b36SAndroid Build Coastguard Worker	// variation. This is useful because such APEXes require extra dependencies.
1201*333d2b36SAndroid Build Coastguard Worker	if sanitizeable, ok := ctx.Module().(Sanitizeable); ok {
1202*333d2b36SAndroid Build Coastguard Worker		enabled := sanitizeable.IsSanitizerEnabled(ctx.Config(), s.sanitizer.name())
1203*333d2b36SAndroid Build Coastguard Worker		if enabled {
1204*333d2b36SAndroid Build Coastguard Worker			return []string{s.sanitizer.variationName()}
1205*333d2b36SAndroid Build Coastguard Worker		} else {
1206*333d2b36SAndroid Build Coastguard Worker			return []string{""}
1207*333d2b36SAndroid Build Coastguard Worker		}
1208*333d2b36SAndroid Build Coastguard Worker	}
1209*333d2b36SAndroid Build Coastguard Worker
1210*333d2b36SAndroid Build Coastguard Worker	return []string{""}
1211*333d2b36SAndroid Build Coastguard Worker}
1212*333d2b36SAndroid Build Coastguard Worker
1213*333d2b36SAndroid Build Coastguard Workerfunc (s *sanitizerSplitMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
1214*333d2b36SAndroid Build Coastguard Worker	if c, ok := ctx.Module().(PlatformSanitizeable); ok {
1215*333d2b36SAndroid Build Coastguard Worker		if !c.SanitizableDepTagChecker()(ctx.DepTag()) {
1216*333d2b36SAndroid Build Coastguard Worker			// If the dependency is through a non-sanitizable tag, use the
1217*333d2b36SAndroid Build Coastguard Worker			// non-sanitized variation
1218*333d2b36SAndroid Build Coastguard Worker			return ""
1219*333d2b36SAndroid Build Coastguard Worker		}
1220*333d2b36SAndroid Build Coastguard Worker
1221*333d2b36SAndroid Build Coastguard Worker		return sourceVariation
1222*333d2b36SAndroid Build Coastguard Worker	} else if _, ok := ctx.Module().(JniSanitizeable); ok {
1223*333d2b36SAndroid Build Coastguard Worker		// TODO: this should call into JniSanitizable.IsSanitizerEnabledForJni but
1224*333d2b36SAndroid Build Coastguard Worker		// that is short-circuited for now
1225*333d2b36SAndroid Build Coastguard Worker		return ""
1226*333d2b36SAndroid Build Coastguard Worker	} else {
1227*333d2b36SAndroid Build Coastguard Worker		// Otherwise, do not rock the boat.
1228*333d2b36SAndroid Build Coastguard Worker		return sourceVariation
1229*333d2b36SAndroid Build Coastguard Worker	}
1230*333d2b36SAndroid Build Coastguard Worker}
1231*333d2b36SAndroid Build Coastguard Worker
1232*333d2b36SAndroid Build Coastguard Workerfunc (s *sanitizerSplitMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
1233*333d2b36SAndroid Build Coastguard Worker	if d, ok := ctx.Module().(PlatformSanitizeable); ok {
1234*333d2b36SAndroid Build Coastguard Worker		if !d.SanitizePropDefined() ||
1235*333d2b36SAndroid Build Coastguard Worker			d.SanitizeNever() ||
1236*333d2b36SAndroid Build Coastguard Worker			d.IsSanitizerExplicitlyDisabled(s.sanitizer) ||
1237*333d2b36SAndroid Build Coastguard Worker			!d.SanitizerSupported(s.sanitizer) {
1238*333d2b36SAndroid Build Coastguard Worker			// If a module opts out of a sanitizer, use its non-sanitized variation
1239*333d2b36SAndroid Build Coastguard Worker			return ""
1240*333d2b36SAndroid Build Coastguard Worker		}
1241*333d2b36SAndroid Build Coastguard Worker
1242*333d2b36SAndroid Build Coastguard Worker		// Binaries are always built in the variation they requested.
1243*333d2b36SAndroid Build Coastguard Worker		if d.Binary() {
1244*333d2b36SAndroid Build Coastguard Worker			if d.IsSanitizerEnabled(s.sanitizer) {
1245*333d2b36SAndroid Build Coastguard Worker				return s.sanitizer.variationName()
1246*333d2b36SAndroid Build Coastguard Worker			} else {
1247*333d2b36SAndroid Build Coastguard Worker				return ""
1248*333d2b36SAndroid Build Coastguard Worker			}
1249*333d2b36SAndroid Build Coastguard Worker		}
1250*333d2b36SAndroid Build Coastguard Worker
1251*333d2b36SAndroid Build Coastguard Worker		// If a shared library requests to be sanitized, it will be built for that
1252*333d2b36SAndroid Build Coastguard Worker		// sanitizer. Otherwise, some sanitizers propagate through shared library
1253*333d2b36SAndroid Build Coastguard Worker		// dependency edges, some do not.
1254*333d2b36SAndroid Build Coastguard Worker		if !d.StaticallyLinked() && !d.Header() {
1255*333d2b36SAndroid Build Coastguard Worker			if d.IsSanitizerEnabled(s.sanitizer) {
1256*333d2b36SAndroid Build Coastguard Worker				return s.sanitizer.variationName()
1257*333d2b36SAndroid Build Coastguard Worker			}
1258*333d2b36SAndroid Build Coastguard Worker
1259*333d2b36SAndroid Build Coastguard Worker			// Some sanitizers do not propagate to shared dependencies
1260*333d2b36SAndroid Build Coastguard Worker			if !s.sanitizer.shouldPropagateToSharedLibraryDeps() {
1261*333d2b36SAndroid Build Coastguard Worker				return ""
1262*333d2b36SAndroid Build Coastguard Worker			}
1263*333d2b36SAndroid Build Coastguard Worker		}
1264*333d2b36SAndroid Build Coastguard Worker
1265*333d2b36SAndroid Build Coastguard Worker		// Static and header libraries inherit whether they are sanitized from the
1266*333d2b36SAndroid Build Coastguard Worker		// module they are linked into
1267*333d2b36SAndroid Build Coastguard Worker		return incomingVariation
1268*333d2b36SAndroid Build Coastguard Worker	} else if d, ok := ctx.Module().(Sanitizeable); ok {
1269*333d2b36SAndroid Build Coastguard Worker		// If an APEX contains a sanitized module, it will be built in the variation
1270*333d2b36SAndroid Build Coastguard Worker		// corresponding to that sanitizer.
1271*333d2b36SAndroid Build Coastguard Worker		enabled := d.IsSanitizerEnabled(ctx.Config(), s.sanitizer.name())
1272*333d2b36SAndroid Build Coastguard Worker		if enabled {
1273*333d2b36SAndroid Build Coastguard Worker			return s.sanitizer.variationName()
1274*333d2b36SAndroid Build Coastguard Worker		}
1275*333d2b36SAndroid Build Coastguard Worker
1276*333d2b36SAndroid Build Coastguard Worker		return incomingVariation
1277*333d2b36SAndroid Build Coastguard Worker	}
1278*333d2b36SAndroid Build Coastguard Worker
1279*333d2b36SAndroid Build Coastguard Worker	return ""
1280*333d2b36SAndroid Build Coastguard Worker}
1281*333d2b36SAndroid Build Coastguard Worker
1282*333d2b36SAndroid Build Coastguard Workerfunc (s *sanitizerSplitMutator) Mutate(mctx android.BottomUpMutatorContext, variationName string) {
1283*333d2b36SAndroid Build Coastguard Worker	sanitizerVariation := variationName == s.sanitizer.variationName()
1284*333d2b36SAndroid Build Coastguard Worker
1285*333d2b36SAndroid Build Coastguard Worker	if c, ok := mctx.Module().(PlatformSanitizeable); ok && c.SanitizePropDefined() {
1286*333d2b36SAndroid Build Coastguard Worker		sanitizerEnabled := c.IsSanitizerEnabled(s.sanitizer)
1287*333d2b36SAndroid Build Coastguard Worker
1288*333d2b36SAndroid Build Coastguard Worker		oneMakeVariation := false
1289*333d2b36SAndroid Build Coastguard Worker		if c.StaticallyLinked() || c.Header() {
1290*333d2b36SAndroid Build Coastguard Worker			if s.sanitizer != cfi && s.sanitizer != scs && s.sanitizer != Hwasan {
1291*333d2b36SAndroid Build Coastguard Worker				// These sanitizers export only one variation to Make. For the rest,
1292*333d2b36SAndroid Build Coastguard Worker				// Make targets can depend on both the sanitized and non-sanitized
1293*333d2b36SAndroid Build Coastguard Worker				// versions.
1294*333d2b36SAndroid Build Coastguard Worker				oneMakeVariation = true
1295*333d2b36SAndroid Build Coastguard Worker			}
1296*333d2b36SAndroid Build Coastguard Worker		} else if !c.Binary() {
1297*333d2b36SAndroid Build Coastguard Worker			// Shared library. These are the sanitizers that do propagate through shared
1298*333d2b36SAndroid Build Coastguard Worker			// library dependencies and therefore can cause multiple variations of a
1299*333d2b36SAndroid Build Coastguard Worker			// shared library to be built.
1300*333d2b36SAndroid Build Coastguard Worker			if s.sanitizer != cfi && s.sanitizer != Hwasan && s.sanitizer != scs && s.sanitizer != Asan {
1301*333d2b36SAndroid Build Coastguard Worker				oneMakeVariation = true
1302*333d2b36SAndroid Build Coastguard Worker			}
1303*333d2b36SAndroid Build Coastguard Worker		}
1304*333d2b36SAndroid Build Coastguard Worker
1305*333d2b36SAndroid Build Coastguard Worker		if oneMakeVariation {
1306*333d2b36SAndroid Build Coastguard Worker			if sanitizerEnabled != sanitizerVariation {
1307*333d2b36SAndroid Build Coastguard Worker				c.SetPreventInstall()
1308*333d2b36SAndroid Build Coastguard Worker				c.SetHideFromMake()
1309*333d2b36SAndroid Build Coastguard Worker			}
1310*333d2b36SAndroid Build Coastguard Worker		}
1311*333d2b36SAndroid Build Coastguard Worker
1312*333d2b36SAndroid Build Coastguard Worker		if sanitizerVariation {
1313*333d2b36SAndroid Build Coastguard Worker			c.SetSanitizer(s.sanitizer, true)
1314*333d2b36SAndroid Build Coastguard Worker
1315*333d2b36SAndroid Build Coastguard Worker			// CFI is incompatible with ASAN so disable it in ASAN variations
1316*333d2b36SAndroid Build Coastguard Worker			if s.sanitizer.incompatibleWithCfi() {
1317*333d2b36SAndroid Build Coastguard Worker				cfiSupported := mctx.Module().(PlatformSanitizeable).SanitizerSupported(cfi)
1318*333d2b36SAndroid Build Coastguard Worker				if mctx.Device() && cfiSupported {
1319*333d2b36SAndroid Build Coastguard Worker					c.SetSanitizer(cfi, false)
1320*333d2b36SAndroid Build Coastguard Worker				}
1321*333d2b36SAndroid Build Coastguard Worker			}
1322*333d2b36SAndroid Build Coastguard Worker
1323*333d2b36SAndroid Build Coastguard Worker			// locate the asan libraries under /data/asan
1324*333d2b36SAndroid Build Coastguard Worker			if !c.Binary() && !c.StaticallyLinked() && !c.Header() && mctx.Device() && s.sanitizer == Asan && sanitizerEnabled {
1325*333d2b36SAndroid Build Coastguard Worker				c.SetInSanitizerDir()
1326*333d2b36SAndroid Build Coastguard Worker			}
1327*333d2b36SAndroid Build Coastguard Worker
1328*333d2b36SAndroid Build Coastguard Worker			if c.StaticallyLinked() && c.ExportedToMake() {
1329*333d2b36SAndroid Build Coastguard Worker				if s.sanitizer == Hwasan {
1330*333d2b36SAndroid Build Coastguard Worker					hwasanStaticLibs(mctx.Config()).add(c, c.Module().Name())
1331*333d2b36SAndroid Build Coastguard Worker				} else if s.sanitizer == cfi {
1332*333d2b36SAndroid Build Coastguard Worker					cfiStaticLibs(mctx.Config()).add(c, c.Module().Name())
1333*333d2b36SAndroid Build Coastguard Worker				} else if s.sanitizer == Memtag_stack {
1334*333d2b36SAndroid Build Coastguard Worker					memtagStackStaticLibs(mctx.Config()).add(c, c.Module().Name())
1335*333d2b36SAndroid Build Coastguard Worker				}
1336*333d2b36SAndroid Build Coastguard Worker			}
1337*333d2b36SAndroid Build Coastguard Worker		} else if c.IsSanitizerEnabled(s.sanitizer) {
1338*333d2b36SAndroid Build Coastguard Worker			// Disable the sanitizer for the non-sanitized variation
1339*333d2b36SAndroid Build Coastguard Worker			c.SetSanitizer(s.sanitizer, false)
1340*333d2b36SAndroid Build Coastguard Worker		}
1341*333d2b36SAndroid Build Coastguard Worker	} else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok {
1342*333d2b36SAndroid Build Coastguard Worker		// If an APEX has sanitized dependencies, it gets a few more dependencies
1343*333d2b36SAndroid Build Coastguard Worker		if sanitizerVariation {
1344*333d2b36SAndroid Build Coastguard Worker			sanitizeable.AddSanitizerDependencies(mctx, s.sanitizer.name())
1345*333d2b36SAndroid Build Coastguard Worker		}
1346*333d2b36SAndroid Build Coastguard Worker	}
1347*333d2b36SAndroid Build Coastguard Worker}
1348*333d2b36SAndroid Build Coastguard Worker
1349*333d2b36SAndroid Build Coastguard Workerfunc (c *Module) SanitizeNever() bool {
1350*333d2b36SAndroid Build Coastguard Worker	return c.sanitize.Properties.ForceDisable || Bool(c.sanitize.Properties.SanitizeMutated.Never)
1351*333d2b36SAndroid Build Coastguard Worker}
1352*333d2b36SAndroid Build Coastguard Worker
1353*333d2b36SAndroid Build Coastguard Workerfunc (c *Module) IsSanitizerExplicitlyDisabled(t SanitizerType) bool {
1354*333d2b36SAndroid Build Coastguard Worker	return c.sanitize.isSanitizerExplicitlyDisabled(t)
1355*333d2b36SAndroid Build Coastguard Worker}
1356*333d2b36SAndroid Build Coastguard Worker
1357*333d2b36SAndroid Build Coastguard Worker// Propagate the ubsan minimal runtime dependency when there are integer overflow sanitized static dependencies.
1358*333d2b36SAndroid Build Coastguard Workerfunc sanitizerRuntimeDepsMutator(mctx android.BottomUpMutatorContext) {
1359*333d2b36SAndroid Build Coastguard Worker	// Change this to PlatformSanitizable when/if non-cc modules support ubsan sanitizers.
1360*333d2b36SAndroid Build Coastguard Worker	if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
1361*333d2b36SAndroid Build Coastguard Worker		if c.sanitize.Properties.ForceDisable {
1362*333d2b36SAndroid Build Coastguard Worker			return
1363*333d2b36SAndroid Build Coastguard Worker		}
1364*333d2b36SAndroid Build Coastguard Worker		isSanitizableDependencyTag := c.SanitizableDepTagChecker()
1365*333d2b36SAndroid Build Coastguard Worker		mctx.WalkDeps(func(child, parent android.Module) bool {
1366*333d2b36SAndroid Build Coastguard Worker			if !isSanitizableDependencyTag(mctx.OtherModuleDependencyTag(child)) {
1367*333d2b36SAndroid Build Coastguard Worker				return false
1368*333d2b36SAndroid Build Coastguard Worker			}
1369*333d2b36SAndroid Build Coastguard Worker
1370*333d2b36SAndroid Build Coastguard Worker			d, ok := child.(*Module)
1371*333d2b36SAndroid Build Coastguard Worker			if !ok || !d.static() {
1372*333d2b36SAndroid Build Coastguard Worker				return false
1373*333d2b36SAndroid Build Coastguard Worker			}
1374*333d2b36SAndroid Build Coastguard Worker			if d.sanitize != nil && !d.sanitize.Properties.ForceDisable {
1375*333d2b36SAndroid Build Coastguard Worker				if enableMinimalRuntime(d.sanitize) {
1376*333d2b36SAndroid Build Coastguard Worker					// If a static dependency is built with the minimal runtime,
1377*333d2b36SAndroid Build Coastguard Worker					// make sure we include the ubsan minimal runtime.
1378*333d2b36SAndroid Build Coastguard Worker					c.sanitize.Properties.MinimalRuntimeDep = true
1379*333d2b36SAndroid Build Coastguard Worker				} else if enableUbsanRuntime(d.sanitize) {
1380*333d2b36SAndroid Build Coastguard Worker					// If a static dependency runs with full ubsan diagnostics,
1381*333d2b36SAndroid Build Coastguard Worker					// make sure we include the ubsan runtime.
1382*333d2b36SAndroid Build Coastguard Worker					c.sanitize.Properties.UbsanRuntimeDep = true
1383*333d2b36SAndroid Build Coastguard Worker				}
1384*333d2b36SAndroid Build Coastguard Worker
1385*333d2b36SAndroid Build Coastguard Worker				if c.sanitize.Properties.MinimalRuntimeDep &&
1386*333d2b36SAndroid Build Coastguard Worker					c.sanitize.Properties.UbsanRuntimeDep {
1387*333d2b36SAndroid Build Coastguard Worker					// both flags that this mutator might set are true, so don't bother recursing
1388*333d2b36SAndroid Build Coastguard Worker					return false
1389*333d2b36SAndroid Build Coastguard Worker				}
1390*333d2b36SAndroid Build Coastguard Worker
1391*333d2b36SAndroid Build Coastguard Worker				if c.Os() == android.Linux {
1392*333d2b36SAndroid Build Coastguard Worker					c.sanitize.Properties.BuiltinsDep = true
1393*333d2b36SAndroid Build Coastguard Worker				}
1394*333d2b36SAndroid Build Coastguard Worker
1395*333d2b36SAndroid Build Coastguard Worker				return true
1396*333d2b36SAndroid Build Coastguard Worker			}
1397*333d2b36SAndroid Build Coastguard Worker
1398*333d2b36SAndroid Build Coastguard Worker			return false
1399*333d2b36SAndroid Build Coastguard Worker		})
1400*333d2b36SAndroid Build Coastguard Worker	}
1401*333d2b36SAndroid Build Coastguard Worker}
1402*333d2b36SAndroid Build Coastguard Worker
1403*333d2b36SAndroid Build Coastguard Worker// Add the dependency to the runtime library for each of the sanitizer variants
1404*333d2b36SAndroid Build Coastguard Workerfunc sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
1405*333d2b36SAndroid Build Coastguard Worker	if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
1406*333d2b36SAndroid Build Coastguard Worker		if !c.Enabled(mctx) {
1407*333d2b36SAndroid Build Coastguard Worker			return
1408*333d2b36SAndroid Build Coastguard Worker		}
1409*333d2b36SAndroid Build Coastguard Worker		if c.sanitize.Properties.ForceDisable {
1410*333d2b36SAndroid Build Coastguard Worker			return
1411*333d2b36SAndroid Build Coastguard Worker		}
1412*333d2b36SAndroid Build Coastguard Worker
1413*333d2b36SAndroid Build Coastguard Worker		var sanitizers []string
1414*333d2b36SAndroid Build Coastguard Worker		var diagSanitizers []string
1415*333d2b36SAndroid Build Coastguard Worker
1416*333d2b36SAndroid Build Coastguard Worker		sanProps := &c.sanitize.Properties.SanitizeMutated
1417*333d2b36SAndroid Build Coastguard Worker
1418*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.All_undefined) {
1419*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "undefined")
1420*333d2b36SAndroid Build Coastguard Worker		} else {
1421*333d2b36SAndroid Build Coastguard Worker			if Bool(sanProps.Undefined) {
1422*333d2b36SAndroid Build Coastguard Worker				sanitizers = append(sanitizers,
1423*333d2b36SAndroid Build Coastguard Worker					"bool",
1424*333d2b36SAndroid Build Coastguard Worker					"integer-divide-by-zero",
1425*333d2b36SAndroid Build Coastguard Worker					"return",
1426*333d2b36SAndroid Build Coastguard Worker					"returns-nonnull-attribute",
1427*333d2b36SAndroid Build Coastguard Worker					"shift-exponent",
1428*333d2b36SAndroid Build Coastguard Worker					"unreachable",
1429*333d2b36SAndroid Build Coastguard Worker					"vla-bound",
1430*333d2b36SAndroid Build Coastguard Worker					// TODO(danalbert): The following checks currently have compiler performance issues.
1431*333d2b36SAndroid Build Coastguard Worker					//"alignment",
1432*333d2b36SAndroid Build Coastguard Worker					//"bounds",
1433*333d2b36SAndroid Build Coastguard Worker					//"enum",
1434*333d2b36SAndroid Build Coastguard Worker					//"float-cast-overflow",
1435*333d2b36SAndroid Build Coastguard Worker					//"float-divide-by-zero",
1436*333d2b36SAndroid Build Coastguard Worker					//"nonnull-attribute",
1437*333d2b36SAndroid Build Coastguard Worker					//"null",
1438*333d2b36SAndroid Build Coastguard Worker					//"shift-base",
1439*333d2b36SAndroid Build Coastguard Worker					//"signed-integer-overflow",
1440*333d2b36SAndroid Build Coastguard Worker				)
1441*333d2b36SAndroid Build Coastguard Worker
1442*333d2b36SAndroid Build Coastguard Worker				if mctx.Config().ReleaseBuildObjectSizeSanitizer() {
1443*333d2b36SAndroid Build Coastguard Worker					sanitizers = append(sanitizers, "object-size")
1444*333d2b36SAndroid Build Coastguard Worker				}
1445*333d2b36SAndroid Build Coastguard Worker			}
1446*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, sanProps.Misc_undefined...)
1447*333d2b36SAndroid Build Coastguard Worker		}
1448*333d2b36SAndroid Build Coastguard Worker
1449*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Diag.Undefined) {
1450*333d2b36SAndroid Build Coastguard Worker			diagSanitizers = append(diagSanitizers, "undefined")
1451*333d2b36SAndroid Build Coastguard Worker		}
1452*333d2b36SAndroid Build Coastguard Worker
1453*333d2b36SAndroid Build Coastguard Worker		diagSanitizers = append(diagSanitizers, sanProps.Diag.Misc_undefined...)
1454*333d2b36SAndroid Build Coastguard Worker
1455*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Address) {
1456*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "address")
1457*333d2b36SAndroid Build Coastguard Worker			diagSanitizers = append(diagSanitizers, "address")
1458*333d2b36SAndroid Build Coastguard Worker		}
1459*333d2b36SAndroid Build Coastguard Worker
1460*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Hwaddress) {
1461*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "hwaddress")
1462*333d2b36SAndroid Build Coastguard Worker		}
1463*333d2b36SAndroid Build Coastguard Worker
1464*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Thread) {
1465*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "thread")
1466*333d2b36SAndroid Build Coastguard Worker		}
1467*333d2b36SAndroid Build Coastguard Worker
1468*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Safestack) {
1469*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "safe-stack")
1470*333d2b36SAndroid Build Coastguard Worker		}
1471*333d2b36SAndroid Build Coastguard Worker
1472*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Cfi) {
1473*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "cfi")
1474*333d2b36SAndroid Build Coastguard Worker
1475*333d2b36SAndroid Build Coastguard Worker			if Bool(sanProps.Diag.Cfi) {
1476*333d2b36SAndroid Build Coastguard Worker				diagSanitizers = append(diagSanitizers, "cfi")
1477*333d2b36SAndroid Build Coastguard Worker			}
1478*333d2b36SAndroid Build Coastguard Worker		}
1479*333d2b36SAndroid Build Coastguard Worker
1480*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Integer_overflow) {
1481*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "unsigned-integer-overflow")
1482*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "signed-integer-overflow")
1483*333d2b36SAndroid Build Coastguard Worker			if Bool(sanProps.Diag.Integer_overflow) {
1484*333d2b36SAndroid Build Coastguard Worker				diagSanitizers = append(diagSanitizers, "unsigned-integer-overflow")
1485*333d2b36SAndroid Build Coastguard Worker				diagSanitizers = append(diagSanitizers, "signed-integer-overflow")
1486*333d2b36SAndroid Build Coastguard Worker			}
1487*333d2b36SAndroid Build Coastguard Worker		}
1488*333d2b36SAndroid Build Coastguard Worker
1489*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Scudo) {
1490*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "scudo")
1491*333d2b36SAndroid Build Coastguard Worker		}
1492*333d2b36SAndroid Build Coastguard Worker
1493*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Scs) {
1494*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "shadow-call-stack")
1495*333d2b36SAndroid Build Coastguard Worker		}
1496*333d2b36SAndroid Build Coastguard Worker
1497*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Memtag_heap) && c.Binary() {
1498*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "memtag-heap")
1499*333d2b36SAndroid Build Coastguard Worker		}
1500*333d2b36SAndroid Build Coastguard Worker
1501*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Memtag_stack) {
1502*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "memtag-stack")
1503*333d2b36SAndroid Build Coastguard Worker		}
1504*333d2b36SAndroid Build Coastguard Worker
1505*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Memtag_globals) {
1506*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "memtag-globals")
1507*333d2b36SAndroid Build Coastguard Worker		}
1508*333d2b36SAndroid Build Coastguard Worker
1509*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Fuzzer) {
1510*333d2b36SAndroid Build Coastguard Worker			sanitizers = append(sanitizers, "fuzzer-no-link")
1511*333d2b36SAndroid Build Coastguard Worker		}
1512*333d2b36SAndroid Build Coastguard Worker
1513*333d2b36SAndroid Build Coastguard Worker		// Save the list of sanitizers. These will be used again when generating
1514*333d2b36SAndroid Build Coastguard Worker		// the build rules (for Cflags, etc.)
1515*333d2b36SAndroid Build Coastguard Worker		c.sanitize.Properties.Sanitizers = sanitizers
1516*333d2b36SAndroid Build Coastguard Worker		c.sanitize.Properties.DiagSanitizers = diagSanitizers
1517*333d2b36SAndroid Build Coastguard Worker
1518*333d2b36SAndroid Build Coastguard Worker		// TODO(b/150822854) Hosts have a different default behavior and assume the runtime library is used.
1519*333d2b36SAndroid Build Coastguard Worker		if c.Host() {
1520*333d2b36SAndroid Build Coastguard Worker			diagSanitizers = sanitizers
1521*333d2b36SAndroid Build Coastguard Worker		}
1522*333d2b36SAndroid Build Coastguard Worker
1523*333d2b36SAndroid Build Coastguard Worker		addStaticDeps := func(dep string, hideSymbols bool) {
1524*333d2b36SAndroid Build Coastguard Worker			// static executable gets static runtime libs
1525*333d2b36SAndroid Build Coastguard Worker			depTag := libraryDependencyTag{Kind: staticLibraryDependency, unexportedSymbols: hideSymbols}
1526*333d2b36SAndroid Build Coastguard Worker			variations := append(mctx.Target().Variations(),
1527*333d2b36SAndroid Build Coastguard Worker				blueprint.Variation{Mutator: "link", Variation: "static"})
1528*333d2b36SAndroid Build Coastguard Worker			if c.Device() {
1529*333d2b36SAndroid Build Coastguard Worker				variations = append(variations, c.ImageVariation())
1530*333d2b36SAndroid Build Coastguard Worker			}
1531*333d2b36SAndroid Build Coastguard Worker			if c.UseSdk() {
1532*333d2b36SAndroid Build Coastguard Worker				variations = append(variations,
1533*333d2b36SAndroid Build Coastguard Worker					blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
1534*333d2b36SAndroid Build Coastguard Worker			}
1535*333d2b36SAndroid Build Coastguard Worker			mctx.AddFarVariationDependencies(variations, depTag, dep)
1536*333d2b36SAndroid Build Coastguard Worker		}
1537*333d2b36SAndroid Build Coastguard Worker
1538*333d2b36SAndroid Build Coastguard Worker		// Determine the runtime library required
1539*333d2b36SAndroid Build Coastguard Worker		runtimeSharedLibrary := ""
1540*333d2b36SAndroid Build Coastguard Worker		toolchain := c.toolchain(mctx)
1541*333d2b36SAndroid Build Coastguard Worker		if Bool(sanProps.Address) {
1542*333d2b36SAndroid Build Coastguard Worker			if toolchain.Musl() || (c.staticBinary() && toolchain.Bionic()) {
1543*333d2b36SAndroid Build Coastguard Worker				// Use a static runtime for musl to match what clang does for glibc.
1544*333d2b36SAndroid Build Coastguard Worker				addStaticDeps(config.AddressSanitizerStaticRuntimeLibrary(), false)
1545*333d2b36SAndroid Build Coastguard Worker				addStaticDeps(config.AddressSanitizerCXXStaticRuntimeLibrary(), false)
1546*333d2b36SAndroid Build Coastguard Worker			} else {
1547*333d2b36SAndroid Build Coastguard Worker				runtimeSharedLibrary = config.AddressSanitizerRuntimeLibrary()
1548*333d2b36SAndroid Build Coastguard Worker			}
1549*333d2b36SAndroid Build Coastguard Worker		} else if Bool(sanProps.Hwaddress) {
1550*333d2b36SAndroid Build Coastguard Worker			if c.staticBinary() {
1551*333d2b36SAndroid Build Coastguard Worker				addStaticDeps(config.HWAddressSanitizerStaticLibrary(), true)
1552*333d2b36SAndroid Build Coastguard Worker				addStaticDeps("libdl", false)
1553*333d2b36SAndroid Build Coastguard Worker			} else {
1554*333d2b36SAndroid Build Coastguard Worker				runtimeSharedLibrary = config.HWAddressSanitizerRuntimeLibrary()
1555*333d2b36SAndroid Build Coastguard Worker			}
1556*333d2b36SAndroid Build Coastguard Worker		} else if Bool(sanProps.Thread) {
1557*333d2b36SAndroid Build Coastguard Worker			runtimeSharedLibrary = config.ThreadSanitizerRuntimeLibrary()
1558*333d2b36SAndroid Build Coastguard Worker		} else if Bool(sanProps.Scudo) {
1559*333d2b36SAndroid Build Coastguard Worker			if len(diagSanitizers) == 0 && !c.sanitize.Properties.UbsanRuntimeDep {
1560*333d2b36SAndroid Build Coastguard Worker				runtimeSharedLibrary = config.ScudoMinimalRuntimeLibrary()
1561*333d2b36SAndroid Build Coastguard Worker			} else {
1562*333d2b36SAndroid Build Coastguard Worker				runtimeSharedLibrary = config.ScudoRuntimeLibrary()
1563*333d2b36SAndroid Build Coastguard Worker			}
1564*333d2b36SAndroid Build Coastguard Worker		} else if len(diagSanitizers) > 0 || c.sanitize.Properties.UbsanRuntimeDep ||
1565*333d2b36SAndroid Build Coastguard Worker			Bool(sanProps.Fuzzer) ||
1566*333d2b36SAndroid Build Coastguard Worker			Bool(sanProps.Undefined) ||
1567*333d2b36SAndroid Build Coastguard Worker			Bool(sanProps.All_undefined) {
1568*333d2b36SAndroid Build Coastguard Worker			if toolchain.Musl() || c.staticBinary() {
1569*333d2b36SAndroid Build Coastguard Worker				// Use a static runtime for static binaries.  For sanitized glibc binaries the runtime is
1570*333d2b36SAndroid Build Coastguard Worker				// added automatically by clang, but for static glibc binaries that are not sanitized but
1571*333d2b36SAndroid Build Coastguard Worker				// have a sanitized dependency the runtime needs to be added manually.
1572*333d2b36SAndroid Build Coastguard Worker				// Also manually add a static runtime for musl to match what clang does for glibc.
1573*333d2b36SAndroid Build Coastguard Worker				// Otherwise dlopening libraries that depend on libclang_rt.ubsan_standalone.so fails with:
1574*333d2b36SAndroid Build Coastguard Worker				// Error relocating ...: initial-exec TLS resolves to dynamic definition
1575*333d2b36SAndroid Build Coastguard Worker				addStaticDeps(config.UndefinedBehaviorSanitizerRuntimeLibrary()+".static", true)
1576*333d2b36SAndroid Build Coastguard Worker			} else {
1577*333d2b36SAndroid Build Coastguard Worker				runtimeSharedLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary()
1578*333d2b36SAndroid Build Coastguard Worker			}
1579*333d2b36SAndroid Build Coastguard Worker		}
1580*333d2b36SAndroid Build Coastguard Worker
1581*333d2b36SAndroid Build Coastguard Worker		if enableMinimalRuntime(c.sanitize) || c.sanitize.Properties.MinimalRuntimeDep {
1582*333d2b36SAndroid Build Coastguard Worker			addStaticDeps(config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(), true)
1583*333d2b36SAndroid Build Coastguard Worker		}
1584*333d2b36SAndroid Build Coastguard Worker		if c.sanitize.Properties.BuiltinsDep {
1585*333d2b36SAndroid Build Coastguard Worker			addStaticDeps(config.BuiltinsRuntimeLibrary(), true)
1586*333d2b36SAndroid Build Coastguard Worker		}
1587*333d2b36SAndroid Build Coastguard Worker
1588*333d2b36SAndroid Build Coastguard Worker		if runtimeSharedLibrary != "" && (toolchain.Bionic() || toolchain.Musl()) {
1589*333d2b36SAndroid Build Coastguard Worker			// UBSan is supported on non-bionic linux host builds as well
1590*333d2b36SAndroid Build Coastguard Worker
1591*333d2b36SAndroid Build Coastguard Worker			// Adding dependency to the runtime library. We are using *FarVariation*
1592*333d2b36SAndroid Build Coastguard Worker			// because the runtime libraries themselves are not mutated by sanitizer
1593*333d2b36SAndroid Build Coastguard Worker			// mutators and thus don't have sanitizer variants whereas this module
1594*333d2b36SAndroid Build Coastguard Worker			// has been already mutated.
1595*333d2b36SAndroid Build Coastguard Worker			//
1596*333d2b36SAndroid Build Coastguard Worker			// Note that by adding dependency with {static|shared}DepTag, the lib is
1597*333d2b36SAndroid Build Coastguard Worker			// added to libFlags and LOCAL_SHARED_LIBRARIES by cc.Module
1598*333d2b36SAndroid Build Coastguard Worker			if c.staticBinary() {
1599*333d2b36SAndroid Build Coastguard Worker				// Most sanitizers are either disabled for static binaries or have already
1600*333d2b36SAndroid Build Coastguard Worker				// handled the static binary case above through a direct call to addStaticDeps.
1601*333d2b36SAndroid Build Coastguard Worker				// If not, treat the runtime shared library as a static library and hope for
1602*333d2b36SAndroid Build Coastguard Worker				// the best.
1603*333d2b36SAndroid Build Coastguard Worker				addStaticDeps(runtimeSharedLibrary, true)
1604*333d2b36SAndroid Build Coastguard Worker			} else if !c.static() && !c.Header() {
1605*333d2b36SAndroid Build Coastguard Worker				// Skip apex dependency check for sharedLibraryDependency
1606*333d2b36SAndroid Build Coastguard Worker				// when sanitizer diags are enabled. Skipping the check will allow
1607*333d2b36SAndroid Build Coastguard Worker				// building with diag libraries without having to list the
1608*333d2b36SAndroid Build Coastguard Worker				// dependency in Apex's allowed_deps file.
1609*333d2b36SAndroid Build Coastguard Worker				diagEnabled := len(diagSanitizers) > 0
1610*333d2b36SAndroid Build Coastguard Worker				// dynamic executable and shared libs get shared runtime libs
1611*333d2b36SAndroid Build Coastguard Worker				depTag := libraryDependencyTag{
1612*333d2b36SAndroid Build Coastguard Worker					Kind:  sharedLibraryDependency,
1613*333d2b36SAndroid Build Coastguard Worker					Order: earlyLibraryDependency,
1614*333d2b36SAndroid Build Coastguard Worker
1615*333d2b36SAndroid Build Coastguard Worker					skipApexAllowedDependenciesCheck: diagEnabled,
1616*333d2b36SAndroid Build Coastguard Worker				}
1617*333d2b36SAndroid Build Coastguard Worker				variations := append(mctx.Target().Variations(),
1618*333d2b36SAndroid Build Coastguard Worker					blueprint.Variation{Mutator: "link", Variation: "shared"})
1619*333d2b36SAndroid Build Coastguard Worker				if c.Device() {
1620*333d2b36SAndroid Build Coastguard Worker					variations = append(variations, c.ImageVariation())
1621*333d2b36SAndroid Build Coastguard Worker				}
1622*333d2b36SAndroid Build Coastguard Worker				if c.UseSdk() {
1623*333d2b36SAndroid Build Coastguard Worker					variations = append(variations,
1624*333d2b36SAndroid Build Coastguard Worker						blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
1625*333d2b36SAndroid Build Coastguard Worker				}
1626*333d2b36SAndroid Build Coastguard Worker				AddSharedLibDependenciesWithVersions(mctx, c, variations, depTag, runtimeSharedLibrary, "", true)
1627*333d2b36SAndroid Build Coastguard Worker			}
1628*333d2b36SAndroid Build Coastguard Worker			// static lib does not have dependency to the runtime library. The
1629*333d2b36SAndroid Build Coastguard Worker			// dependency will be added to the executables or shared libs using
1630*333d2b36SAndroid Build Coastguard Worker			// the static lib.
1631*333d2b36SAndroid Build Coastguard Worker		}
1632*333d2b36SAndroid Build Coastguard Worker	}
1633*333d2b36SAndroid Build Coastguard Worker}
1634*333d2b36SAndroid Build Coastguard Worker
1635*333d2b36SAndroid Build Coastguard Workertype Sanitizeable interface {
1636*333d2b36SAndroid Build Coastguard Worker	android.Module
1637*333d2b36SAndroid Build Coastguard Worker	IsSanitizerEnabled(config android.Config, sanitizerName string) bool
1638*333d2b36SAndroid Build Coastguard Worker	EnableSanitizer(sanitizerName string)
1639*333d2b36SAndroid Build Coastguard Worker	AddSanitizerDependencies(ctx android.BottomUpMutatorContext, sanitizerName string)
1640*333d2b36SAndroid Build Coastguard Worker}
1641*333d2b36SAndroid Build Coastguard Worker
1642*333d2b36SAndroid Build Coastguard Workertype JniSanitizeable interface {
1643*333d2b36SAndroid Build Coastguard Worker	android.Module
1644*333d2b36SAndroid Build Coastguard Worker	IsSanitizerEnabledForJni(ctx android.BaseModuleContext, sanitizerName string) bool
1645*333d2b36SAndroid Build Coastguard Worker}
1646*333d2b36SAndroid Build Coastguard Worker
1647*333d2b36SAndroid Build Coastguard Workerfunc (c *Module) MinimalRuntimeDep() bool {
1648*333d2b36SAndroid Build Coastguard Worker	return c.sanitize.Properties.MinimalRuntimeDep
1649*333d2b36SAndroid Build Coastguard Worker}
1650*333d2b36SAndroid Build Coastguard Worker
1651*333d2b36SAndroid Build Coastguard Workerfunc (c *Module) UbsanRuntimeDep() bool {
1652*333d2b36SAndroid Build Coastguard Worker	return c.sanitize.Properties.UbsanRuntimeDep
1653*333d2b36SAndroid Build Coastguard Worker}
1654*333d2b36SAndroid Build Coastguard Worker
1655*333d2b36SAndroid Build Coastguard Workerfunc (c *Module) SanitizePropDefined() bool {
1656*333d2b36SAndroid Build Coastguard Worker	return c.sanitize != nil
1657*333d2b36SAndroid Build Coastguard Worker}
1658*333d2b36SAndroid Build Coastguard Worker
1659*333d2b36SAndroid Build Coastguard Workerfunc (c *Module) IsSanitizerEnabled(t SanitizerType) bool {
1660*333d2b36SAndroid Build Coastguard Worker	return c.sanitize.isSanitizerEnabled(t)
1661*333d2b36SAndroid Build Coastguard Worker}
1662*333d2b36SAndroid Build Coastguard Worker
1663*333d2b36SAndroid Build Coastguard Workerfunc (c *Module) StaticallyLinked() bool {
1664*333d2b36SAndroid Build Coastguard Worker	return c.static()
1665*333d2b36SAndroid Build Coastguard Worker}
1666*333d2b36SAndroid Build Coastguard Worker
1667*333d2b36SAndroid Build Coastguard Workerfunc (c *Module) SetInSanitizerDir() {
1668*333d2b36SAndroid Build Coastguard Worker	if c.sanitize != nil {
1669*333d2b36SAndroid Build Coastguard Worker		c.sanitize.Properties.InSanitizerDir = true
1670*333d2b36SAndroid Build Coastguard Worker	}
1671*333d2b36SAndroid Build Coastguard Worker}
1672*333d2b36SAndroid Build Coastguard Worker
1673*333d2b36SAndroid Build Coastguard Workerfunc (c *Module) SetSanitizer(t SanitizerType, b bool) {
1674*333d2b36SAndroid Build Coastguard Worker	if c.sanitize != nil {
1675*333d2b36SAndroid Build Coastguard Worker		c.sanitize.SetSanitizer(t, b)
1676*333d2b36SAndroid Build Coastguard Worker	}
1677*333d2b36SAndroid Build Coastguard Worker}
1678*333d2b36SAndroid Build Coastguard Worker
1679*333d2b36SAndroid Build Coastguard Workervar _ PlatformSanitizeable = (*Module)(nil)
1680*333d2b36SAndroid Build Coastguard Worker
1681*333d2b36SAndroid Build Coastguard Workertype sanitizerStaticLibsMap struct {
1682*333d2b36SAndroid Build Coastguard Worker	// libsMap contains one list of modules per each image and each arch.
1683*333d2b36SAndroid Build Coastguard Worker	// e.g. libs[vendor]["arm"] contains arm modules installed to vendor
1684*333d2b36SAndroid Build Coastguard Worker	libsMap       map[ImageVariantType]map[string][]string
1685*333d2b36SAndroid Build Coastguard Worker	libsMapLock   sync.Mutex
1686*333d2b36SAndroid Build Coastguard Worker	sanitizerType SanitizerType
1687*333d2b36SAndroid Build Coastguard Worker}
1688*333d2b36SAndroid Build Coastguard Worker
1689*333d2b36SAndroid Build Coastguard Workerfunc newSanitizerStaticLibsMap(t SanitizerType) *sanitizerStaticLibsMap {
1690*333d2b36SAndroid Build Coastguard Worker	return &sanitizerStaticLibsMap{
1691*333d2b36SAndroid Build Coastguard Worker		sanitizerType: t,
1692*333d2b36SAndroid Build Coastguard Worker		libsMap:       make(map[ImageVariantType]map[string][]string),
1693*333d2b36SAndroid Build Coastguard Worker	}
1694*333d2b36SAndroid Build Coastguard Worker}
1695*333d2b36SAndroid Build Coastguard Worker
1696*333d2b36SAndroid Build Coastguard Worker// Add the current module to sanitizer static libs maps
1697*333d2b36SAndroid Build Coastguard Worker// Each module should pass its exported name as names of Make and Soong can differ.
1698*333d2b36SAndroid Build Coastguard Workerfunc (s *sanitizerStaticLibsMap) add(c LinkableInterface, name string) {
1699*333d2b36SAndroid Build Coastguard Worker	image := GetImageVariantType(c)
1700*333d2b36SAndroid Build Coastguard Worker	arch := c.Module().Target().Arch.ArchType.String()
1701*333d2b36SAndroid Build Coastguard Worker
1702*333d2b36SAndroid Build Coastguard Worker	s.libsMapLock.Lock()
1703*333d2b36SAndroid Build Coastguard Worker	defer s.libsMapLock.Unlock()
1704*333d2b36SAndroid Build Coastguard Worker
1705*333d2b36SAndroid Build Coastguard Worker	if _, ok := s.libsMap[image]; !ok {
1706*333d2b36SAndroid Build Coastguard Worker		s.libsMap[image] = make(map[string][]string)
1707*333d2b36SAndroid Build Coastguard Worker	}
1708*333d2b36SAndroid Build Coastguard Worker
1709*333d2b36SAndroid Build Coastguard Worker	s.libsMap[image][arch] = append(s.libsMap[image][arch], name)
1710*333d2b36SAndroid Build Coastguard Worker}
1711*333d2b36SAndroid Build Coastguard Worker
1712*333d2b36SAndroid Build Coastguard Worker// Exports makefile variables in the following format:
1713*333d2b36SAndroid Build Coastguard Worker// SOONG_{sanitizer}_{image}_{arch}_STATIC_LIBRARIES
1714*333d2b36SAndroid Build Coastguard Worker// e.g. SOONG_cfi_core_x86_STATIC_LIBRARIES
1715*333d2b36SAndroid Build Coastguard Worker// These are to be used by use_soong_sanitized_static_libraries.
1716*333d2b36SAndroid Build Coastguard Worker// See build/make/core/binary.mk for more details.
1717*333d2b36SAndroid Build Coastguard Workerfunc (s *sanitizerStaticLibsMap) exportToMake(ctx android.MakeVarsContext) {
1718*333d2b36SAndroid Build Coastguard Worker	for _, image := range android.SortedKeys(s.libsMap) {
1719*333d2b36SAndroid Build Coastguard Worker		archMap := s.libsMap[ImageVariantType(image)]
1720*333d2b36SAndroid Build Coastguard Worker		for _, arch := range android.SortedKeys(archMap) {
1721*333d2b36SAndroid Build Coastguard Worker			libs := archMap[arch]
1722*333d2b36SAndroid Build Coastguard Worker			sort.Strings(libs)
1723*333d2b36SAndroid Build Coastguard Worker
1724*333d2b36SAndroid Build Coastguard Worker			key := fmt.Sprintf(
1725*333d2b36SAndroid Build Coastguard Worker				"SOONG_%s_%s_%s_STATIC_LIBRARIES",
1726*333d2b36SAndroid Build Coastguard Worker				s.sanitizerType.variationName(),
1727*333d2b36SAndroid Build Coastguard Worker				image, // already upper
1728*333d2b36SAndroid Build Coastguard Worker				arch)
1729*333d2b36SAndroid Build Coastguard Worker
1730*333d2b36SAndroid Build Coastguard Worker			ctx.Strict(key, strings.Join(libs, " "))
1731*333d2b36SAndroid Build Coastguard Worker		}
1732*333d2b36SAndroid Build Coastguard Worker	}
1733*333d2b36SAndroid Build Coastguard Worker}
1734*333d2b36SAndroid Build Coastguard Worker
1735*333d2b36SAndroid Build Coastguard Workervar cfiStaticLibsKey = android.NewOnceKey("cfiStaticLibs")
1736*333d2b36SAndroid Build Coastguard Worker
1737*333d2b36SAndroid Build Coastguard Workerfunc cfiStaticLibs(config android.Config) *sanitizerStaticLibsMap {
1738*333d2b36SAndroid Build Coastguard Worker	return config.Once(cfiStaticLibsKey, func() interface{} {
1739*333d2b36SAndroid Build Coastguard Worker		return newSanitizerStaticLibsMap(cfi)
1740*333d2b36SAndroid Build Coastguard Worker	}).(*sanitizerStaticLibsMap)
1741*333d2b36SAndroid Build Coastguard Worker}
1742*333d2b36SAndroid Build Coastguard Worker
1743*333d2b36SAndroid Build Coastguard Workervar hwasanStaticLibsKey = android.NewOnceKey("hwasanStaticLibs")
1744*333d2b36SAndroid Build Coastguard Worker
1745*333d2b36SAndroid Build Coastguard Workerfunc hwasanStaticLibs(config android.Config) *sanitizerStaticLibsMap {
1746*333d2b36SAndroid Build Coastguard Worker	return config.Once(hwasanStaticLibsKey, func() interface{} {
1747*333d2b36SAndroid Build Coastguard Worker		return newSanitizerStaticLibsMap(Hwasan)
1748*333d2b36SAndroid Build Coastguard Worker	}).(*sanitizerStaticLibsMap)
1749*333d2b36SAndroid Build Coastguard Worker}
1750*333d2b36SAndroid Build Coastguard Worker
1751*333d2b36SAndroid Build Coastguard Workervar memtagStackStaticLibsKey = android.NewOnceKey("memtagStackStaticLibs")
1752*333d2b36SAndroid Build Coastguard Worker
1753*333d2b36SAndroid Build Coastguard Workerfunc memtagStackStaticLibs(config android.Config) *sanitizerStaticLibsMap {
1754*333d2b36SAndroid Build Coastguard Worker	return config.Once(memtagStackStaticLibsKey, func() interface{} {
1755*333d2b36SAndroid Build Coastguard Worker		return newSanitizerStaticLibsMap(Memtag_stack)
1756*333d2b36SAndroid Build Coastguard Worker	}).(*sanitizerStaticLibsMap)
1757*333d2b36SAndroid Build Coastguard Worker}
1758*333d2b36SAndroid Build Coastguard Worker
1759*333d2b36SAndroid Build Coastguard Workerfunc enableMinimalRuntime(sanitize *sanitize) bool {
1760*333d2b36SAndroid Build Coastguard Worker	if sanitize.isSanitizerEnabled(Asan) {
1761*333d2b36SAndroid Build Coastguard Worker		return false
1762*333d2b36SAndroid Build Coastguard Worker	} else if sanitize.isSanitizerEnabled(Hwasan) {
1763*333d2b36SAndroid Build Coastguard Worker		return false
1764*333d2b36SAndroid Build Coastguard Worker	} else if sanitize.isSanitizerEnabled(Fuzzer) {
1765*333d2b36SAndroid Build Coastguard Worker		return false
1766*333d2b36SAndroid Build Coastguard Worker	}
1767*333d2b36SAndroid Build Coastguard Worker
1768*333d2b36SAndroid Build Coastguard Worker	if enableUbsanRuntime(sanitize) {
1769*333d2b36SAndroid Build Coastguard Worker		return false
1770*333d2b36SAndroid Build Coastguard Worker	}
1771*333d2b36SAndroid Build Coastguard Worker
1772*333d2b36SAndroid Build Coastguard Worker	sanitizeProps := &sanitize.Properties.SanitizeMutated
1773*333d2b36SAndroid Build Coastguard Worker	if Bool(sanitizeProps.Diag.Cfi) {
1774*333d2b36SAndroid Build Coastguard Worker		return false
1775*333d2b36SAndroid Build Coastguard Worker	}
1776*333d2b36SAndroid Build Coastguard Worker
1777*333d2b36SAndroid Build Coastguard Worker	return Bool(sanitizeProps.Integer_overflow) ||
1778*333d2b36SAndroid Build Coastguard Worker		len(sanitizeProps.Misc_undefined) > 0 ||
1779*333d2b36SAndroid Build Coastguard Worker		Bool(sanitizeProps.Undefined) ||
1780*333d2b36SAndroid Build Coastguard Worker		Bool(sanitizeProps.All_undefined)
1781*333d2b36SAndroid Build Coastguard Worker}
1782*333d2b36SAndroid Build Coastguard Worker
1783*333d2b36SAndroid Build Coastguard Workerfunc (m *Module) UbsanRuntimeNeeded() bool {
1784*333d2b36SAndroid Build Coastguard Worker	return enableUbsanRuntime(m.sanitize)
1785*333d2b36SAndroid Build Coastguard Worker}
1786*333d2b36SAndroid Build Coastguard Worker
1787*333d2b36SAndroid Build Coastguard Workerfunc (m *Module) MinimalRuntimeNeeded() bool {
1788*333d2b36SAndroid Build Coastguard Worker	return enableMinimalRuntime(m.sanitize)
1789*333d2b36SAndroid Build Coastguard Worker}
1790*333d2b36SAndroid Build Coastguard Worker
1791*333d2b36SAndroid Build Coastguard Workerfunc enableUbsanRuntime(sanitize *sanitize) bool {
1792*333d2b36SAndroid Build Coastguard Worker	sanitizeProps := &sanitize.Properties.SanitizeMutated
1793*333d2b36SAndroid Build Coastguard Worker	return Bool(sanitizeProps.Diag.Integer_overflow) ||
1794*333d2b36SAndroid Build Coastguard Worker		Bool(sanitizeProps.Diag.Undefined) ||
1795*333d2b36SAndroid Build Coastguard Worker		len(sanitizeProps.Diag.Misc_undefined) > 0
1796*333d2b36SAndroid Build Coastguard Worker}
1797*333d2b36SAndroid Build Coastguard Worker
1798*333d2b36SAndroid Build Coastguard Workerfunc cfiMakeVarsProvider(ctx android.MakeVarsContext) {
1799*333d2b36SAndroid Build Coastguard Worker	cfiStaticLibs(ctx.Config()).exportToMake(ctx)
1800*333d2b36SAndroid Build Coastguard Worker}
1801*333d2b36SAndroid Build Coastguard Worker
1802*333d2b36SAndroid Build Coastguard Workerfunc hwasanMakeVarsProvider(ctx android.MakeVarsContext) {
1803*333d2b36SAndroid Build Coastguard Worker	hwasanStaticLibs(ctx.Config()).exportToMake(ctx)
1804*333d2b36SAndroid Build Coastguard Worker}
1805*333d2b36SAndroid Build Coastguard Worker
1806*333d2b36SAndroid Build Coastguard Workerfunc memtagStackMakeVarsProvider(ctx android.MakeVarsContext) {
1807*333d2b36SAndroid Build Coastguard Worker	memtagStackStaticLibs(ctx.Config()).exportToMake(ctx)
1808*333d2b36SAndroid Build Coastguard Worker}
1809*333d2b36SAndroid Build Coastguard Worker
1810*333d2b36SAndroid Build Coastguard Workertype sanitizerLibrariesTxtModule struct {
1811*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
1812*333d2b36SAndroid Build Coastguard Worker
1813*333d2b36SAndroid Build Coastguard Worker	outputFile android.Path
1814*333d2b36SAndroid Build Coastguard Worker}
1815*333d2b36SAndroid Build Coastguard Worker
1816*333d2b36SAndroid Build Coastguard Workervar _ etc.PrebuiltEtcModule = (*sanitizerLibrariesTxtModule)(nil)
1817*333d2b36SAndroid Build Coastguard Worker
1818*333d2b36SAndroid Build Coastguard Workerfunc RegisterSanitizerLibrariesTxtType(ctx android.RegistrationContext) {
1819*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("sanitizer_libraries_txt", sanitizerLibrariesTxtFactory)
1820*333d2b36SAndroid Build Coastguard Worker}
1821*333d2b36SAndroid Build Coastguard Worker
1822*333d2b36SAndroid Build Coastguard Workerfunc sanitizerLibrariesTxtFactory() android.Module {
1823*333d2b36SAndroid Build Coastguard Worker	m := &sanitizerLibrariesTxtModule{}
1824*333d2b36SAndroid Build Coastguard Worker	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
1825*333d2b36SAndroid Build Coastguard Worker	return m
1826*333d2b36SAndroid Build Coastguard Worker}
1827*333d2b36SAndroid Build Coastguard Worker
1828*333d2b36SAndroid Build Coastguard Workertype sanitizerLibraryDependencyTag struct {
1829*333d2b36SAndroid Build Coastguard Worker	blueprint.BaseDependencyTag
1830*333d2b36SAndroid Build Coastguard Worker	android.AlwaysAllowDisabledModuleDependencyTag
1831*333d2b36SAndroid Build Coastguard Worker}
1832*333d2b36SAndroid Build Coastguard Worker
1833*333d2b36SAndroid Build Coastguard Workervar _ android.AllowDisabledModuleDependency = (*sanitizerLibraryDependencyTag)(nil)
1834*333d2b36SAndroid Build Coastguard Worker
1835*333d2b36SAndroid Build Coastguard Workerfunc (txt *sanitizerLibrariesTxtModule) DepsMutator(actx android.BottomUpMutatorContext) {
1836*333d2b36SAndroid Build Coastguard Worker	targets := actx.Config().Targets[android.Android]
1837*333d2b36SAndroid Build Coastguard Worker	depTag := sanitizerLibraryDependencyTag{}
1838*333d2b36SAndroid Build Coastguard Worker
1839*333d2b36SAndroid Build Coastguard Worker	for _, target := range targets {
1840*333d2b36SAndroid Build Coastguard Worker		variation := append(target.Variations(),
1841*333d2b36SAndroid Build Coastguard Worker			blueprint.Variation{Mutator: "image", Variation: ""},
1842*333d2b36SAndroid Build Coastguard Worker			blueprint.Variation{Mutator: "sdk", Variation: ""},
1843*333d2b36SAndroid Build Coastguard Worker			blueprint.Variation{Mutator: "link", Variation: "shared"},
1844*333d2b36SAndroid Build Coastguard Worker		)
1845*333d2b36SAndroid Build Coastguard Worker		for _, lib := range android.SortedStringValues(sanitizerVariables) {
1846*333d2b36SAndroid Build Coastguard Worker			if actx.OtherModuleFarDependencyVariantExists(variation, lib) {
1847*333d2b36SAndroid Build Coastguard Worker				actx.AddFarVariationDependencies(variation, depTag, lib)
1848*333d2b36SAndroid Build Coastguard Worker			}
1849*333d2b36SAndroid Build Coastguard Worker
1850*333d2b36SAndroid Build Coastguard Worker			prebuiltLibName := "prebuilt_" + lib
1851*333d2b36SAndroid Build Coastguard Worker			if actx.OtherModuleFarDependencyVariantExists(variation, prebuiltLibName) {
1852*333d2b36SAndroid Build Coastguard Worker				actx.AddFarVariationDependencies(variation, depTag, prebuiltLibName)
1853*333d2b36SAndroid Build Coastguard Worker			}
1854*333d2b36SAndroid Build Coastguard Worker		}
1855*333d2b36SAndroid Build Coastguard Worker	}
1856*333d2b36SAndroid Build Coastguard Worker
1857*333d2b36SAndroid Build Coastguard Worker}
1858*333d2b36SAndroid Build Coastguard Worker
1859*333d2b36SAndroid Build Coastguard Workerfunc (txt *sanitizerLibrariesTxtModule) getSanitizerLibs(ctx android.ModuleContext) string {
1860*333d2b36SAndroid Build Coastguard Worker	var sanitizerLibStems []string
1861*333d2b36SAndroid Build Coastguard Worker
1862*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDepsIf(func(m android.Module) bool {
1863*333d2b36SAndroid Build Coastguard Worker		if !m.Enabled(ctx) {
1864*333d2b36SAndroid Build Coastguard Worker			return false
1865*333d2b36SAndroid Build Coastguard Worker		}
1866*333d2b36SAndroid Build Coastguard Worker
1867*333d2b36SAndroid Build Coastguard Worker		ccModule, _ := m.(*Module)
1868*333d2b36SAndroid Build Coastguard Worker		if ccModule == nil || ccModule.library == nil || !ccModule.library.shared() {
1869*333d2b36SAndroid Build Coastguard Worker			return false
1870*333d2b36SAndroid Build Coastguard Worker		}
1871*333d2b36SAndroid Build Coastguard Worker
1872*333d2b36SAndroid Build Coastguard Worker		targets := ctx.Config().Targets[android.Android]
1873*333d2b36SAndroid Build Coastguard Worker
1874*333d2b36SAndroid Build Coastguard Worker		for _, target := range targets {
1875*333d2b36SAndroid Build Coastguard Worker			if m.Target().Os == target.Os && m.Target().Arch.ArchType == target.Arch.ArchType {
1876*333d2b36SAndroid Build Coastguard Worker				return true
1877*333d2b36SAndroid Build Coastguard Worker			}
1878*333d2b36SAndroid Build Coastguard Worker		}
1879*333d2b36SAndroid Build Coastguard Worker
1880*333d2b36SAndroid Build Coastguard Worker		return false
1881*333d2b36SAndroid Build Coastguard Worker	}, func(m android.Module) {
1882*333d2b36SAndroid Build Coastguard Worker		ccModule, _ := m.(*Module)
1883*333d2b36SAndroid Build Coastguard Worker		outputFile := ccModule.outputFile
1884*333d2b36SAndroid Build Coastguard Worker		if outputFile.Valid() {
1885*333d2b36SAndroid Build Coastguard Worker			sanitizerLibStems = append(sanitizerLibStems, outputFile.Path().Base())
1886*333d2b36SAndroid Build Coastguard Worker		}
1887*333d2b36SAndroid Build Coastguard Worker	})
1888*333d2b36SAndroid Build Coastguard Worker
1889*333d2b36SAndroid Build Coastguard Worker	sanitizerLibStems = android.SortedUniqueStrings(sanitizerLibStems)
1890*333d2b36SAndroid Build Coastguard Worker	return strings.Join(sanitizerLibStems, "\n")
1891*333d2b36SAndroid Build Coastguard Worker}
1892*333d2b36SAndroid Build Coastguard Worker
1893*333d2b36SAndroid Build Coastguard Workerfunc (txt *sanitizerLibrariesTxtModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1894*333d2b36SAndroid Build Coastguard Worker	filename := txt.Name()
1895*333d2b36SAndroid Build Coastguard Worker
1896*333d2b36SAndroid Build Coastguard Worker	outputFile := android.PathForModuleOut(ctx, filename)
1897*333d2b36SAndroid Build Coastguard Worker	android.WriteFileRule(ctx, outputFile, txt.getSanitizerLibs(ctx))
1898*333d2b36SAndroid Build Coastguard Worker
1899*333d2b36SAndroid Build Coastguard Worker	installPath := android.PathForModuleInstall(ctx, "etc")
1900*333d2b36SAndroid Build Coastguard Worker	ctx.InstallFile(installPath, filename, outputFile)
1901*333d2b36SAndroid Build Coastguard Worker
1902*333d2b36SAndroid Build Coastguard Worker	ctx.SetOutputFiles(android.Paths{outputFile}, "")
1903*333d2b36SAndroid Build Coastguard Worker	txt.outputFile = outputFile
1904*333d2b36SAndroid Build Coastguard Worker}
1905*333d2b36SAndroid Build Coastguard Worker
1906*333d2b36SAndroid Build Coastguard Workerfunc (txt *sanitizerLibrariesTxtModule) PrepareAndroidMKProviderInfo(config android.Config) *android.AndroidMkProviderInfo {
1907*333d2b36SAndroid Build Coastguard Worker	return &android.AndroidMkProviderInfo{
1908*333d2b36SAndroid Build Coastguard Worker		PrimaryInfo: android.AndroidMkInfo{
1909*333d2b36SAndroid Build Coastguard Worker			Class:      "ETC",
1910*333d2b36SAndroid Build Coastguard Worker			OutputFile: android.OptionalPathForPath(txt.outputFile),
1911*333d2b36SAndroid Build Coastguard Worker		},
1912*333d2b36SAndroid Build Coastguard Worker	}
1913*333d2b36SAndroid Build Coastguard Worker}
1914*333d2b36SAndroid Build Coastguard Worker
1915*333d2b36SAndroid Build Coastguard Worker// PrebuiltEtcModule interface
1916*333d2b36SAndroid Build Coastguard Workerfunc (txt *sanitizerLibrariesTxtModule) BaseDir() string {
1917*333d2b36SAndroid Build Coastguard Worker	return "etc"
1918*333d2b36SAndroid Build Coastguard Worker}
1919*333d2b36SAndroid Build Coastguard Worker
1920*333d2b36SAndroid Build Coastguard Worker// PrebuiltEtcModule interface
1921*333d2b36SAndroid Build Coastguard Workerfunc (txt *sanitizerLibrariesTxtModule) SubDir() string {
1922*333d2b36SAndroid Build Coastguard Worker	return ""
1923*333d2b36SAndroid Build Coastguard Worker}
1924