| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 1 | // Copyright 2020 The Android Open Source Project | 
 | 2 | // | 
 | 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 4 | // you may not use this file except in compliance with the License. | 
 | 5 | // You may obtain a copy of the License at | 
 | 6 | // | 
 | 7 | //     http://www.apache.org/licenses/LICENSE-2.0 | 
 | 8 | // | 
 | 9 | // Unless required by applicable law or agreed to in writing, software | 
 | 10 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 12 | // See the License for the specific language governing permissions and | 
 | 13 | // limitations under the License. | 
 | 14 |  | 
 | 15 | package rust | 
 | 16 |  | 
 | 17 | import ( | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 18 | 	"fmt" | 
 | 19 | 	"strings" | 
 | 20 |  | 
 | 21 | 	"github.com/google/blueprint" | 
 | 22 | 	"github.com/google/blueprint/proptools" | 
 | 23 |  | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 24 | 	"android/soong/android" | 
 | 25 | 	"android/soong/cc" | 
 | 26 | 	"android/soong/rust/config" | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 27 | ) | 
 | 28 |  | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 29 | // TODO: When Rust has sanitizer-parity with CC, deduplicate this struct | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 30 | type SanitizeProperties struct { | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 31 | 	// enable AddressSanitizer, HWAddressSanitizer, and others. | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 32 | 	Sanitize struct { | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 33 | 		Address   *bool `android:"arch_variant"` | 
 | 34 | 		Hwaddress *bool `android:"arch_variant"` | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 35 |  | 
 | 36 | 		// Memory-tagging, only available on arm64 | 
 | 37 | 		// if diag.memtag unset or false, enables async memory tagging | 
 | 38 | 		Memtag_heap *bool `android:"arch_variant"` | 
 | 39 | 		Fuzzer      *bool `android:"arch_variant"` | 
 | 40 | 		Never       *bool `android:"arch_variant"` | 
 | 41 |  | 
 | 42 | 		// Sanitizers to run in the diagnostic mode (as opposed to the release mode). | 
 | 43 | 		// Replaces abort() on error with a human-readable error message. | 
 | 44 | 		// Address and Thread sanitizers always run in diagnostic mode. | 
 | 45 | 		Diag struct { | 
 | 46 | 			// Memory-tagging, only available on arm64 | 
 | 47 | 			// requires sanitizer.memtag: true | 
 | 48 | 			// if set, enables sync memory tagging | 
 | 49 | 			Memtag_heap *bool `android:"arch_variant"` | 
 | 50 | 		} | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 51 | 	} | 
| Lukacs T. Berki | 6c71676 | 2022-06-13 20:50:39 +0200 | [diff] [blame] | 52 | 	SanitizerEnabled bool `blueprint:"mutated"` | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 53 |  | 
 | 54 | 	// Used when we need to place libraries in their own directory, such as ASAN. | 
 | 55 | 	InSanitizerDir bool `blueprint:"mutated"` | 
 | 56 | } | 
 | 57 |  | 
 | 58 | var fuzzerFlags = []string{ | 
| Ivan Lozano | 357433a | 2024-02-12 14:13:37 -0500 | [diff] [blame] | 59 | 	"-Z external-clangrt=true", | 
 | 60 |  | 
| Charisee | 5ddec43 | 2022-03-01 03:02:51 +0000 | [diff] [blame] | 61 | 	"-C passes='sancov-module'", | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 62 |  | 
 | 63 | 	"--cfg fuzzing", | 
| Ivan Lozano | c044f5b | 2021-04-02 12:43:28 -0400 | [diff] [blame] | 64 | 	"-C llvm-args=-sanitizer-coverage-level=3", | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 65 | 	"-C llvm-args=-sanitizer-coverage-trace-compares", | 
 | 66 | 	"-C llvm-args=-sanitizer-coverage-inline-8bit-counters", | 
| Ivan Lozano | 1247b3c | 2023-06-12 14:57:44 -0400 | [diff] [blame] | 67 | 	"-C llvm-args=-sanitizer-coverage-pc-table", | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 68 |  | 
| Ivan Lozano | aa7c980 | 2021-08-02 09:43:46 -0400 | [diff] [blame] | 69 | 	// See https://github.com/rust-fuzz/cargo-fuzz/pull/193 | 
 | 70 | 	"-C link-dead-code", | 
 | 71 |  | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 72 | 	// Sancov breaks with lto | 
| Charisee | 5ddec43 | 2022-03-01 03:02:51 +0000 | [diff] [blame] | 73 | 	// TODO: Remove when https://bugs.llvm.org/show_bug.cgi?id=41734 is resolved and sancov-module works with LTO | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 74 | 	"-C lto=no", | 
 | 75 | } | 
 | 76 |  | 
 | 77 | var asanFlags = []string{ | 
| Ivan Lozano | 357433a | 2024-02-12 14:13:37 -0500 | [diff] [blame] | 78 | 	"-Z external-clangrt=true", | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 79 | 	"-Z sanitizer=address", | 
 | 80 | } | 
 | 81 |  | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 82 | // See cc/sanitize.go's hwasanGlobalOptions for global hwasan options. | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 83 | var hwasanFlags = []string{ | 
| Ivan Lozano | 357433a | 2024-02-12 14:13:37 -0500 | [diff] [blame] | 84 | 	"-Z external-clangrt=true", | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 85 | 	"-Z sanitizer=hwaddress", | 
 | 86 | 	"-C target-feature=+tagged-globals", | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 87 |  | 
 | 88 | 	// Flags from cc/sanitize.go hwasanFlags | 
 | 89 | 	"-C llvm-args=--aarch64-enable-global-isel-at-O=-1", | 
 | 90 | 	"-C llvm-args=-fast-isel=false", | 
 | 91 | 	"-C llvm-args=-instcombine-lower-dbg-declare=0", | 
 | 92 |  | 
 | 93 | 	// Additional flags for HWASAN-ified Rust/C interop | 
 | 94 | 	"-C llvm-args=--hwasan-with-ifunc", | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 95 | } | 
 | 96 |  | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 97 | func init() { | 
 | 98 | } | 
 | 99 | func (sanitize *sanitize) props() []interface{} { | 
 | 100 | 	return []interface{}{&sanitize.Properties} | 
 | 101 | } | 
 | 102 |  | 
 | 103 | func (sanitize *sanitize) begin(ctx BaseModuleContext) { | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 104 | 	s := &sanitize.Properties.Sanitize | 
 | 105 |  | 
| Colin Cross | 9759ed7 | 2024-10-29 11:47:46 -0700 | [diff] [blame] | 106 | 	// Disable sanitizers for musl x86 modules, rustc does not support any sanitizers. | 
 | 107 | 	if ctx.Os() == android.LinuxMusl && ctx.Arch().ArchType == android.X86 { | 
 | 108 | 		s.Never = proptools.BoolPtr(true) | 
 | 109 | 	} | 
 | 110 |  | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 111 | 	// Never always wins. | 
 | 112 | 	if Bool(s.Never) { | 
 | 113 | 		return | 
 | 114 | 	} | 
 | 115 |  | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 116 | 	// rust_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {Memtag_heap}). | 
 | 117 | 	if binary, ok := ctx.RustModule().compiler.(binaryInterface); ok && binary.testBinary() { | 
 | 118 | 		if s.Memtag_heap == nil { | 
 | 119 | 			s.Memtag_heap = proptools.BoolPtr(true) | 
 | 120 | 		} | 
 | 121 | 		if s.Diag.Memtag_heap == nil { | 
 | 122 | 			s.Diag.Memtag_heap = proptools.BoolPtr(true) | 
 | 123 | 		} | 
 | 124 | 	} | 
 | 125 |  | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 126 | 	var globalSanitizers []string | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 127 | 	var globalSanitizersDiag []string | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 128 |  | 
 | 129 | 	if ctx.Host() { | 
 | 130 | 		if !ctx.Windows() { | 
 | 131 | 			globalSanitizers = ctx.Config().SanitizeHost() | 
 | 132 | 		} | 
 | 133 | 	} else { | 
 | 134 | 		arches := ctx.Config().SanitizeDeviceArch() | 
 | 135 | 		if len(arches) == 0 || android.InList(ctx.Arch().ArchType.Name, arches) { | 
 | 136 | 			globalSanitizers = ctx.Config().SanitizeDevice() | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 137 | 			globalSanitizersDiag = ctx.Config().SanitizeDeviceDiag() | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 138 | 		} | 
 | 139 | 	} | 
 | 140 |  | 
 | 141 | 	if len(globalSanitizers) > 0 { | 
 | 142 | 		var found bool | 
 | 143 |  | 
 | 144 | 		// Global Sanitizers | 
 | 145 | 		if found, globalSanitizers = android.RemoveFromList("hwaddress", globalSanitizers); found && s.Hwaddress == nil { | 
| Ivan Lozano | 6c5b8f4 | 2021-11-15 09:35:12 -0500 | [diff] [blame] | 146 | 			// TODO(b/204776996): HWASan for static Rust binaries isn't supported yet. | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 147 | 			if !ctx.RustModule().StaticExecutable() { | 
 | 148 | 				s.Hwaddress = proptools.BoolPtr(true) | 
 | 149 | 			} | 
 | 150 | 		} | 
 | 151 |  | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 152 | 		if found, globalSanitizers = android.RemoveFromList("memtag_heap", globalSanitizers); found && s.Memtag_heap == nil { | 
 | 153 | 			if !ctx.Config().MemtagHeapDisabledForPath(ctx.ModuleDir()) { | 
 | 154 | 				s.Memtag_heap = proptools.BoolPtr(true) | 
 | 155 | 			} | 
 | 156 | 		} | 
 | 157 |  | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 158 | 		if found, globalSanitizers = android.RemoveFromList("address", globalSanitizers); found && s.Address == nil { | 
 | 159 | 			s.Address = proptools.BoolPtr(true) | 
 | 160 | 		} | 
 | 161 |  | 
 | 162 | 		if found, globalSanitizers = android.RemoveFromList("fuzzer", globalSanitizers); found && s.Fuzzer == nil { | 
| Ivan Lozano | 6c5b8f4 | 2021-11-15 09:35:12 -0500 | [diff] [blame] | 163 | 			// TODO(b/204776996): HWASan for static Rust binaries isn't supported yet, and fuzzer enables HWAsan | 
 | 164 | 			if !ctx.RustModule().StaticExecutable() { | 
 | 165 | 				s.Fuzzer = proptools.BoolPtr(true) | 
 | 166 | 			} | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 167 | 		} | 
 | 168 |  | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 169 | 		// Global Diag Sanitizers | 
 | 170 | 		if found, globalSanitizersDiag = android.RemoveFromList("memtag_heap", globalSanitizersDiag); found && | 
 | 171 | 			s.Diag.Memtag_heap == nil && Bool(s.Memtag_heap) { | 
 | 172 | 			s.Diag.Memtag_heap = proptools.BoolPtr(true) | 
 | 173 | 		} | 
 | 174 | 	} | 
 | 175 |  | 
 | 176 | 	// Enable Memtag for all components in the include paths (for Aarch64 only) | 
| Colin Cross | 1faf823 | 2022-06-24 18:42:32 -0700 | [diff] [blame] | 177 | 	if ctx.Arch().ArchType == android.Arm64 && ctx.Os().Bionic() { | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 178 | 		if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) { | 
 | 179 | 			if s.Memtag_heap == nil { | 
 | 180 | 				s.Memtag_heap = proptools.BoolPtr(true) | 
 | 181 | 			} | 
 | 182 | 			if s.Diag.Memtag_heap == nil { | 
 | 183 | 				s.Diag.Memtag_heap = proptools.BoolPtr(true) | 
 | 184 | 			} | 
 | 185 | 		} else if ctx.Config().MemtagHeapAsyncEnabledForPath(ctx.ModuleDir()) { | 
 | 186 | 			if s.Memtag_heap == nil { | 
 | 187 | 				s.Memtag_heap = proptools.BoolPtr(true) | 
 | 188 | 			} | 
 | 189 | 		} | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 190 | 	} | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 191 |  | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 192 | 	// HWASan requires AArch64 hardware feature (top-byte-ignore). | 
| Colin Cross | 1faf823 | 2022-06-24 18:42:32 -0700 | [diff] [blame] | 193 | 	if ctx.Arch().ArchType != android.Arm64 || !ctx.Os().Bionic() { | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 194 | 		s.Hwaddress = nil | 
 | 195 | 	} | 
 | 196 |  | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 197 | 	// HWASan ramdisk (which is built from recovery) goes over some bootloader limit. | 
 | 198 | 	// Keep libc instrumented so that ramdisk / vendor_ramdisk / recovery can run hwasan-instrumented code if necessary. | 
 | 199 | 	if (ctx.RustModule().InRamdisk() || ctx.RustModule().InVendorRamdisk() || ctx.RustModule().InRecovery()) && !strings.HasPrefix(ctx.ModuleDir(), "bionic/libc") { | 
 | 200 | 		s.Hwaddress = nil | 
 | 201 | 	} | 
 | 202 |  | 
 | 203 | 	if Bool(s.Hwaddress) { | 
 | 204 | 		s.Address = nil | 
 | 205 | 	} | 
 | 206 |  | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 207 | 	// Memtag_heap is only implemented on AArch64. | 
| Colin Cross | 1faf823 | 2022-06-24 18:42:32 -0700 | [diff] [blame] | 208 | 	if ctx.Arch().ArchType != android.Arm64 || !ctx.Os().Bionic() { | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 209 | 		s.Memtag_heap = nil | 
 | 210 | 	} | 
 | 211 |  | 
| Florian Mayer | 296d595 | 2022-10-12 19:30:14 +0000 | [diff] [blame] | 212 | 	// TODO:(b/178369775) | 
| Ivan Lozano | 2fcbffa | 2023-07-27 10:40:52 -0400 | [diff] [blame] | 213 | 	// For now sanitizing is only supported on non-windows targets | 
 | 214 | 	if ctx.Os() != android.Windows && (Bool(s.Hwaddress) || Bool(s.Address) || Bool(s.Memtag_heap) || Bool(s.Fuzzer)) { | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 215 | 		sanitize.Properties.SanitizerEnabled = true | 
 | 216 | 	} | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 217 | } | 
 | 218 |  | 
 | 219 | type sanitize struct { | 
 | 220 | 	Properties SanitizeProperties | 
 | 221 | } | 
 | 222 |  | 
 | 223 | func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags, PathDeps) { | 
 | 224 | 	if !sanitize.Properties.SanitizerEnabled { | 
 | 225 | 		return flags, deps | 
 | 226 | 	} | 
| Ivan Lozano | 408d373 | 2023-07-27 13:28:08 -0400 | [diff] [blame] | 227 |  | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 228 | 	if Bool(sanitize.Properties.Sanitize.Fuzzer) { | 
 | 229 | 		flags.RustFlags = append(flags.RustFlags, fuzzerFlags...) | 
| Ivan Lozano | 408d373 | 2023-07-27 13:28:08 -0400 | [diff] [blame] | 230 | 	} | 
 | 231 |  | 
 | 232 | 	if Bool(sanitize.Properties.Sanitize.Hwaddress) { | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 233 | 		flags.RustFlags = append(flags.RustFlags, hwasanFlags...) | 
| Ivan Lozano | 408d373 | 2023-07-27 13:28:08 -0400 | [diff] [blame] | 234 | 	} | 
 | 235 |  | 
 | 236 | 	if Bool(sanitize.Properties.Sanitize.Address) { | 
| Ivan Lozano | f3e8fc3 | 2021-11-13 07:43:54 -0500 | [diff] [blame] | 237 | 		flags.RustFlags = append(flags.RustFlags, asanFlags...) | 
| Ivan Lozano | 2fcbffa | 2023-07-27 10:40:52 -0400 | [diff] [blame] | 238 | 		if ctx.Host() { | 
 | 239 | 			// -nodefaultlibs (provided with libc++) prevents the driver from linking | 
 | 240 | 			// libraries needed with -fsanitize=address. http://b/18650275 (WAI) | 
 | 241 | 			flags.LinkFlags = append(flags.LinkFlags, []string{"-Wl,--no-as-needed"}...) | 
 | 242 | 		} | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 243 | 	} | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 244 | 	return flags, deps | 
 | 245 | } | 
 | 246 |  | 
 | 247 | func (sanitize *sanitize) deps(ctx BaseModuleContext, deps Deps) Deps { | 
 | 248 | 	return deps | 
 | 249 | } | 
 | 250 |  | 
 | 251 | func rustSanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) { | 
 | 252 | 	if mod, ok := mctx.Module().(*Module); ok && mod.sanitize != nil { | 
| Cole Faust | a963b94 | 2024-04-11 17:43:00 -0700 | [diff] [blame] | 253 | 		if !mod.Enabled(mctx) { | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 254 | 			return | 
 | 255 | 		} | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 256 |  | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 257 | 		if Bool(mod.sanitize.Properties.Sanitize.Memtag_heap) && mod.Binary() { | 
 | 258 | 			noteDep := "note_memtag_heap_async" | 
 | 259 | 			if Bool(mod.sanitize.Properties.Sanitize.Diag.Memtag_heap) { | 
 | 260 | 				noteDep = "note_memtag_heap_sync" | 
 | 261 | 			} | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 262 | 			depTag := cc.StaticDepTag(true) | 
 | 263 | 			variations := append(mctx.Target().Variations(), | 
 | 264 | 				blueprint.Variation{Mutator: "link", Variation: "static"}) | 
 | 265 | 			if mod.Device() { | 
 | 266 | 				variations = append(variations, mod.ImageVariation()) | 
 | 267 | 			} | 
 | 268 | 			mctx.AddFarVariationDependencies(variations, depTag, noteDep) | 
 | 269 | 		} | 
 | 270 |  | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 271 | 		variations := mctx.Target().Variations() | 
 | 272 | 		var depTag blueprint.DependencyTag | 
 | 273 | 		var deps []string | 
 | 274 |  | 
| Ivan Lozano | 408d373 | 2023-07-27 13:28:08 -0400 | [diff] [blame] | 275 | 		if mod.IsSanitizerEnabled(cc.Asan) { | 
| Ivan Lozano | 2fcbffa | 2023-07-27 10:40:52 -0400 | [diff] [blame] | 276 | 			if mod.Host() { | 
 | 277 | 				variations = append(variations, | 
 | 278 | 					blueprint.Variation{Mutator: "link", Variation: "static"}) | 
 | 279 | 				depTag = cc.StaticDepTag(false) | 
 | 280 | 				deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan.static")} | 
 | 281 | 			} else { | 
 | 282 | 				variations = append(variations, | 
 | 283 | 					blueprint.Variation{Mutator: "link", Variation: "shared"}) | 
 | 284 | 				depTag = cc.SharedDepTag() | 
 | 285 | 				deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan")} | 
 | 286 | 			} | 
| Ivan Lozano | 408d373 | 2023-07-27 13:28:08 -0400 | [diff] [blame] | 287 | 		} else if mod.IsSanitizerEnabled(cc.Hwasan) { | 
| Ivan Lozano | 6c5b8f4 | 2021-11-15 09:35:12 -0500 | [diff] [blame] | 288 | 			// TODO(b/204776996): HWASan for static Rust binaries isn't supported yet. | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 289 | 			if binary, ok := mod.compiler.(binaryInterface); ok { | 
 | 290 | 				if binary.staticallyLinked() { | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 291 | 					mctx.ModuleErrorf("HWASan is not supported for static Rust executables yet.") | 
 | 292 | 				} | 
 | 293 | 			} | 
 | 294 |  | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 295 | 			// Always link against the shared library -- static binaries will pull in the static | 
 | 296 | 			// library during final link if necessary | 
 | 297 | 			variations = append(variations, | 
 | 298 | 				blueprint.Variation{Mutator: "link", Variation: "shared"}) | 
 | 299 | 			depTag = cc.SharedDepTag() | 
 | 300 | 			deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "hwasan")} | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 301 | 		} | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 302 |  | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 303 | 		if len(deps) > 0 { | 
 | 304 | 			mctx.AddFarVariationDependencies(variations, depTag, deps...) | 
 | 305 | 		} | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 306 | 	} | 
 | 307 | } | 
 | 308 |  | 
 | 309 | func (sanitize *sanitize) SetSanitizer(t cc.SanitizerType, b bool) { | 
 | 310 | 	sanitizerSet := false | 
 | 311 | 	switch t { | 
 | 312 | 	case cc.Fuzzer: | 
| Colin Cross | 9759ed7 | 2024-10-29 11:47:46 -0700 | [diff] [blame] | 313 | 		sanitize.Properties.Sanitize.Fuzzer = proptools.BoolPtr(b) | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 314 | 		sanitizerSet = true | 
 | 315 | 	case cc.Asan: | 
| Colin Cross | 9759ed7 | 2024-10-29 11:47:46 -0700 | [diff] [blame] | 316 | 		sanitize.Properties.Sanitize.Address = proptools.BoolPtr(b) | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 317 | 		sanitizerSet = true | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 318 | 	case cc.Hwasan: | 
| Colin Cross | 9759ed7 | 2024-10-29 11:47:46 -0700 | [diff] [blame] | 319 | 		sanitize.Properties.Sanitize.Hwaddress = proptools.BoolPtr(b) | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 320 | 		sanitizerSet = true | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 321 | 	case cc.Memtag_heap: | 
| Colin Cross | 9759ed7 | 2024-10-29 11:47:46 -0700 | [diff] [blame] | 322 | 		sanitize.Properties.Sanitize.Memtag_heap = proptools.BoolPtr(b) | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 323 | 		sanitizerSet = true | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 324 | 	default: | 
 | 325 | 		panic(fmt.Errorf("setting unsupported sanitizerType %d", t)) | 
 | 326 | 	} | 
 | 327 | 	if b && sanitizerSet { | 
 | 328 | 		sanitize.Properties.SanitizerEnabled = true | 
 | 329 | 	} | 
 | 330 | } | 
 | 331 |  | 
| Ivan Lozano | d7586b6 | 2021-04-01 09:49:36 -0400 | [diff] [blame] | 332 | func (m *Module) UbsanRuntimeNeeded() bool { | 
 | 333 | 	return false | 
 | 334 | } | 
 | 335 |  | 
 | 336 | func (m *Module) MinimalRuntimeNeeded() bool { | 
 | 337 | 	return false | 
 | 338 | } | 
 | 339 |  | 
 | 340 | func (m *Module) UbsanRuntimeDep() bool { | 
 | 341 | 	return false | 
 | 342 | } | 
 | 343 |  | 
 | 344 | func (m *Module) MinimalRuntimeDep() bool { | 
 | 345 | 	return false | 
 | 346 | } | 
 | 347 |  | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 348 | // Check if the sanitizer is explicitly disabled (as opposed to nil by | 
 | 349 | // virtue of not being set). | 
 | 350 | func (sanitize *sanitize) isSanitizerExplicitlyDisabled(t cc.SanitizerType) bool { | 
 | 351 | 	if sanitize == nil { | 
 | 352 | 		return false | 
 | 353 | 	} | 
 | 354 | 	if Bool(sanitize.Properties.Sanitize.Never) { | 
 | 355 | 		return true | 
 | 356 | 	} | 
 | 357 | 	sanitizerVal := sanitize.getSanitizerBoolPtr(t) | 
 | 358 | 	return sanitizerVal != nil && *sanitizerVal == false | 
 | 359 | } | 
 | 360 |  | 
 | 361 | // There isn't an analog of the method above (ie:isSanitizerExplicitlyEnabled) | 
 | 362 | // because enabling a sanitizer either directly (via the blueprint) or | 
 | 363 | // indirectly (via a mutator) sets the bool ptr to true, and you can't | 
 | 364 | // distinguish between the cases. It isn't needed though - both cases can be | 
 | 365 | // treated identically. | 
 | 366 | func (sanitize *sanitize) isSanitizerEnabled(t cc.SanitizerType) bool { | 
 | 367 | 	if sanitize == nil || !sanitize.Properties.SanitizerEnabled { | 
 | 368 | 		return false | 
 | 369 | 	} | 
 | 370 |  | 
 | 371 | 	sanitizerVal := sanitize.getSanitizerBoolPtr(t) | 
 | 372 | 	return sanitizerVal != nil && *sanitizerVal == true | 
 | 373 | } | 
 | 374 |  | 
 | 375 | func (sanitize *sanitize) getSanitizerBoolPtr(t cc.SanitizerType) *bool { | 
 | 376 | 	switch t { | 
 | 377 | 	case cc.Fuzzer: | 
 | 378 | 		return sanitize.Properties.Sanitize.Fuzzer | 
 | 379 | 	case cc.Asan: | 
 | 380 | 		return sanitize.Properties.Sanitize.Address | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 381 | 	case cc.Hwasan: | 
 | 382 | 		return sanitize.Properties.Sanitize.Hwaddress | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 383 | 	case cc.Memtag_heap: | 
 | 384 | 		return sanitize.Properties.Sanitize.Memtag_heap | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 385 | 	default: | 
 | 386 | 		return nil | 
 | 387 | 	} | 
 | 388 | } | 
 | 389 |  | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 390 | func (sanitize *sanitize) AndroidMk(ctx AndroidMkContext, entries *android.AndroidMkEntries) { | 
 | 391 | 	// Add a suffix for hwasan rlib libraries to allow surfacing both the sanitized and | 
 | 392 | 	// non-sanitized variants to make without a name conflict. | 
 | 393 | 	if entries.Class == "RLIB_LIBRARIES" || entries.Class == "STATIC_LIBRARIES" { | 
 | 394 | 		if sanitize.isSanitizerEnabled(cc.Hwasan) { | 
 | 395 | 			entries.SubName += ".hwasan" | 
 | 396 | 		} | 
 | 397 | 	} | 
 | 398 | } | 
 | 399 |  | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 400 | func (mod *Module) SanitizerSupported(t cc.SanitizerType) bool { | 
| Ivan Lozano | 2fcbffa | 2023-07-27 10:40:52 -0400 | [diff] [blame] | 401 | 	// Sanitizers are not supported on Windows targets. | 
 | 402 | 	if mod.Os() == android.Windows { | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 403 | 		return false | 
 | 404 | 	} | 
 | 405 | 	switch t { | 
 | 406 | 	case cc.Fuzzer: | 
 | 407 | 		return true | 
 | 408 | 	case cc.Asan: | 
 | 409 | 		return true | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 410 | 	case cc.Hwasan: | 
| Ivan Lozano | 5482d6a | 2021-11-01 10:13:25 -0400 | [diff] [blame] | 411 | 		// TODO(b/180495975): HWASan for static Rust binaries isn't supported yet. | 
 | 412 | 		if mod.StaticExecutable() { | 
 | 413 | 			return false | 
 | 414 | 		} | 
| Tri Vo | 0a74c3e | 2021-04-01 13:59:27 -0700 | [diff] [blame] | 415 | 		return true | 
| Ivan Lozano | 62cd038 | 2021-11-01 10:27:54 -0400 | [diff] [blame] | 416 | 	case cc.Memtag_heap: | 
 | 417 | 		return true | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 418 | 	default: | 
 | 419 | 		return false | 
 | 420 | 	} | 
 | 421 | } | 
 | 422 |  | 
 | 423 | func (mod *Module) IsSanitizerEnabled(t cc.SanitizerType) bool { | 
 | 424 | 	return mod.sanitize.isSanitizerEnabled(t) | 
 | 425 | } | 
 | 426 |  | 
 | 427 | func (mod *Module) IsSanitizerExplicitlyDisabled(t cc.SanitizerType) bool { | 
| Ivan Lozano | 2fcbffa | 2023-07-27 10:40:52 -0400 | [diff] [blame] | 428 | 	// Sanitizers are not supported on Windows targets. | 
 | 429 | 	if mod.Os() == android.Windows { | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 430 | 		return true | 
 | 431 | 	} | 
 | 432 |  | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 433 | 	return mod.sanitize.isSanitizerExplicitlyDisabled(t) | 
 | 434 | } | 
 | 435 |  | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 436 | func (mod *Module) SetSanitizer(t cc.SanitizerType, b bool) { | 
 | 437 | 	if !Bool(mod.sanitize.Properties.Sanitize.Never) { | 
 | 438 | 		mod.sanitize.SetSanitizer(t, b) | 
 | 439 | 	} | 
 | 440 | } | 
 | 441 |  | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 442 | func (mod *Module) StaticallyLinked() bool { | 
 | 443 | 	if lib, ok := mod.compiler.(libraryInterface); ok { | 
| Tri Vo | 505b0e8 | 2021-04-08 15:50:48 -0700 | [diff] [blame] | 444 | 		return lib.rlib() || lib.static() | 
| Ivan Lozano | 21fa0a5 | 2021-11-01 09:19:45 -0400 | [diff] [blame] | 445 | 	} else if binary, ok := mod.compiler.(binaryInterface); ok { | 
 | 446 | 		return binary.staticallyLinked() | 
| Ivan Lozano | 6cd99e6 | 2020-02-11 08:24:25 -0500 | [diff] [blame] | 447 | 	} | 
 | 448 | 	return false | 
 | 449 | } | 
 | 450 |  | 
 | 451 | func (mod *Module) SetInSanitizerDir() { | 
 | 452 | 	mod.sanitize.Properties.InSanitizerDir = true | 
 | 453 | } | 
 | 454 |  | 
 | 455 | func (mod *Module) SanitizeNever() bool { | 
 | 456 | 	return Bool(mod.sanitize.Properties.Sanitize.Never) | 
 | 457 | } | 
 | 458 |  | 
 | 459 | var _ cc.PlatformSanitizeable = (*Module)(nil) | 
 | 460 |  | 
 | 461 | func IsSanitizableDependencyTag(tag blueprint.DependencyTag) bool { | 
 | 462 | 	switch t := tag.(type) { | 
 | 463 | 	case dependencyTag: | 
 | 464 | 		return t.library | 
 | 465 | 	default: | 
 | 466 | 		return cc.IsSanitizableDependencyTag(tag) | 
 | 467 | 	} | 
 | 468 | } | 
 | 469 |  | 
 | 470 | func (m *Module) SanitizableDepTagChecker() cc.SantizableDependencyTagChecker { | 
 | 471 | 	return IsSanitizableDependencyTag | 
 | 472 | } |