1# Copyright 2022 The Chromium Authors 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import("//build/config/cronet/config.gni") 6import("//build/config/sanitizers/sanitizers.gni") 7import("//build_overrides/partition_alloc.gni") 8 9if (is_apple) { 10 import("//build/config/features.gni") 11} 12 13# PartitionAlloc have limited support for MSVC's cl.exe compiler. It can only 14# access the generate "buildflags" and the "raw_ptr" definitions implemented 15# with RawPtrNoOpImpl. Everything else is considered not supported. 16# 17# Since there are no other good ways to detect MSVC's cl.exe, we are reusing the 18# same definition used by Chrome in //base/BUILD.gn. See 19# https://crbug.com/988071. 20is_clang_or_gcc = is_clang || !is_win 21 22# Whether 64-bit pointers are used. 23# A static_assert in partition_alloc_config.h verifies that. 24if (is_nacl) { 25 # NaCl targets don't use 64-bit pointers. 26 has_64_bit_pointers = false 27} else if (current_cpu == "x64" || current_cpu == "arm64" || 28 current_cpu == "loong64" || current_cpu == "riscv64") { 29 has_64_bit_pointers = true 30} else if (current_cpu == "x86" || current_cpu == "arm") { 31 has_64_bit_pointers = false 32} else { 33 assert(false, "Unknown CPU: $current_cpu") 34} 35 36declare_args() { 37 # Causes all the allocations to be routed via allocator_shim.cc. Usually, 38 # the allocator shim will, in turn, route them to Partition Alloc, but 39 # other allocators are also supported by the allocator shim. 40 use_allocator_shim = use_allocator_shim_default && is_clang_or_gcc 41 42 # Whether PartitionAlloc should be available for use or not. 43 # true makes PartitionAlloc linked to the executable or shared library and 44 # makes it available for use. It doesn't mean that the default allocator 45 # is PartitionAlloc, which is governed by |use_partition_alloc_as_malloc|. 46 # 47 # N.B. generally, embedders should look at this GN arg and at the 48 # corresponding buildflag to determine whether to interact with PA 49 # source at all (pulling the component in via GN, including headers, 50 # etc.). There is nothing stopping a lazy embedder from ignoring this 51 # and unconditionally using PA, but such a setup is inadvisable. 52 # 53 # In Chromium, this is set true, except: 54 # 55 # 1. On Cronet bots, because Cronet doesn't use PartitionAlloc at all, 56 # and doesn't wish to incur the library size increase (crbug.com/674570). 57 # 2. On NaCl (through this declaration), where PartitionAlloc doesn't 58 # build at all. 59 use_partition_alloc = !is_nacl && is_clang_or_gcc 60} 61 62if (!is_clang_or_gcc) { 63 assert(!use_partition_alloc, 64 "PartitionAlloc's allocator does not support this compiler") 65 assert(!use_allocator_shim, 66 "PartitionAlloc's allocator shim does not support this compiler") 67} 68 69if (is_nacl) { 70 assert(!use_partition_alloc, "PartitionAlloc doesn't build on NaCl") 71} 72 73declare_args() { 74 # Turns on compiler optimizations in PartitionAlloc in Debug build. 75 # If enabling PartitionAlloc-Everywhere in Debug build for tests in Debug 76 # build, since all memory allocations and deallocations are executed by 77 # non-optimized PartitionAlloc, chrome (including tests) will be much 78 # slower. This will cause debug trybots' timeouts. If we want to debug 79 # PartitionAlloc itself, use partition_alloc_optimized_debug=false. 80 # Otherwise, use partition_alloc_optimized_debug=true to enable optimized 81 # PartitionAlloc. 82 partition_alloc_optimized_debug = true 83 84 # PartitionAlloc-Everywhere (PA-E). Causes allocator_shim.cc to route 85 # calls to PartitionAlloc, rather than some other platform allocator. 86 use_partition_alloc_as_malloc = use_partition_alloc && use_allocator_shim && 87 use_partition_alloc_as_malloc_default 88} 89 90assert(!use_allocator_shim || (is_android || is_apple || is_chromeos || 91 is_fuchsia || is_linux || is_win), 92 "The allocator shim does not (yet) support the platform.") 93 94if (use_allocator_shim && is_win) { 95 # It's hard to override CRT's malloc family in every case in the component 96 # build, and it's very easy to override it partially and to be inconsistent 97 # among allocations and deallocations. Then, we'll crash when PA deallocates 98 # a memory region allocated by the CRT's malloc or vice versa. 99 assert(!is_component_build, 100 "The allocator shim doesn't work for the component build on Windows.") 101} 102 103declare_args() { 104 use_freeslot_bitmap = false 105 106 # Puts the regular and BRP pools right next to each other, so that we can 107 # check "belongs to one of the two pools" with a single bitmask operation. 108 glue_core_pools = false 109 110 # Introduces pointer compression support in PA. These are 4-byte 111 # pointers that can point within the core pools (regular and BRP). 112 # 113 # This is effective only for memory allocated from PartitionAlloc, so it is 114 # recommended to enable PA-E above, but isn't strictly necessary. Embedders 115 # can create and use PA partitions explicitly. 116 enable_pointer_compression_support = false 117 118 # Enables a bounds check when two pointers (at least one being raw_ptr) are 119 # subtracted (if supported by the underlying implementation). 120 enable_pointer_subtraction_check = false 121 122 # Enables a compile-time check that all raw_ptrs to which arithmetic 123 # operations are to be applied are annotated with the AllowPtrArithmetic 124 # trait, 125 enable_pointer_arithmetic_trait_check = true 126} 127 128declare_args() { 129 # Build support for Use-after-Free protection via BackupRefPtr (BRP), 130 # making the raw_ptr<T> implementation to RawPtrBackupRefImpl if active. 131 # 132 # These are effective only for memory allocated from PartitionAlloc, so it is 133 # recommended to enable PA-E above, but isn't strictly necessary. Embedders 134 # can create and use PA partitions explicitly. 135 # 136 # Note that |enable_backup_ref_ptr_support = true| doesn't necessarily enable 137 # BRP protection. It'll be enabled only for partition created with 138 # partition_alloc::PartitionOptions::kEnabled. 139 enable_backup_ref_ptr_support = 140 use_partition_alloc && enable_backup_ref_ptr_support_default 141 142 # RAW_PTR_EXCLUSION macro is disabled on official builds because it increased 143 # binary size. This flag can be used to enable it for official builds too. 144 force_enable_raw_ptr_exclusion = false 145} 146 147assert(!enable_pointer_compression_support || glue_core_pools, 148 "Pointer compression relies on core pools being contiguous.") 149 150declare_args() { 151 # Make explicit calls to ASAN at runtime, e.g. to mark quarrantined memory 152 # as poisoned. Allows ASAN to tell if a particular memory error is protected 153 # by BRP in its reports. 154 # 155 # The implementation of ASan BRP is purpose-built to inspect Chromium 156 # internals and is entangled with `//base` s.t. it cannot be used 157 # outside of Chromium. 158 use_asan_backup_ref_ptr = 159 build_with_chromium && is_asan && 160 (is_win || is_android || is_linux || is_mac || is_chromeos) 161 162 # Use probe-on-destruct unowned ptr detection with ASAN. 163 use_asan_unowned_ptr = false 164} 165 166# Use the version of raw_ptr<T> that allows the embedder to implement custom 167# logic. 168use_hookable_raw_ptr = use_asan_backup_ref_ptr 169 170declare_args() { 171 # - put_ref_count_in_previous_slot: place the ref-count at the end of the 172 # previous slot (or in metadata if a slot starts on the page boundary), as 173 # opposed to the beginning of the slot. 174 # - enable_backup_ref_ptr_slow_checks: enable additional safety checks that 175 # are too expensive to have on by default. 176 # - enable_dangling_raw_ptr_checks: enable checking raw_ptr do not become 177 # dangling during their lifetime. 178 # - backup_ref_ptr_poison_oob_ptr: poison out-of-bounds (OOB) pointers to 179 # generate an exception in the event that an OOB pointer is dereferenced. 180 put_ref_count_in_previous_slot = 181 put_ref_count_in_previous_slot_default && enable_backup_ref_ptr_support 182 183 enable_backup_ref_ptr_slow_checks = 184 enable_backup_ref_ptr_slow_checks_default && enable_backup_ref_ptr_support 185 186 # Enable the feature flag required to activate backup ref pointers. That is to 187 # say `PartitionAllocBackupRefPtr`. 188 # 189 # This is meant to be used primarily on bots. It is much easier to override 190 # the feature flags using a binary flag instead of updating multiple bots's 191 # scripts to pass command line arguments. 192 enable_backup_ref_ptr_feature_flag = false 193 194 # Build support for Dangling Ptr Detection (DPD) via BackupRefPtr (BRP), 195 # making the raw_ptr<T> implementation to RawPtrBackupRefImpl if active. 196 enable_dangling_raw_ptr_checks = 197 enable_dangling_raw_ptr_checks_default && enable_backup_ref_ptr_support 198 199 # Enable the feature flag required to check for dangling pointers. That is to 200 # say `PartitionAllocDanglingPtr`. 201 # 202 # This is meant to be used primarily on bots. It is much easier to override 203 # the feature flags using a binary flag instead of updating multiple bots's 204 # scripts to pass command line arguments. 205 enable_dangling_raw_ptr_feature_flag = false 206 207 # Enables the dangling raw_ptr checks feature for the performance experiment. 208 # Not every dangling pointers have been fixed or annotated yet. To avoid 209 # accounting for the cost of calling the PA's embedder's callbacks when a 210 # dangling pointer has been detected, this simulates the raw_ptr to be 211 # allowed to dangle. 212 # 213 # This flag is temporary, and isn't used by PA embedders, so it doesn't need 214 # to go through build_overrides 215 enable_dangling_raw_ptr_perf_experiment = false 216 217 # Set to `enable_backup_ref_ptr_support && has_64_bit_pointers` when enabling. 218 backup_ref_ptr_poison_oob_ptr = false 219} 220 221declare_args() { 222 # Shadow metadata is still under development and only supports Linux 223 # for now. 224 enable_shadow_metadata = false 225} 226 227# *Scan is currently only used by Chromium, and supports only 64-bit. 228use_starscan = build_with_chromium && has_64_bit_pointers 229 230pcscan_stack_supported = 231 use_starscan && 232 (current_cpu == "x64" || current_cpu == "x86" || current_cpu == "arm" || 233 current_cpu == "arm64" || current_cpu == "riscv64") 234 235# We want to provide assertions that guard against inconsistent build 236# args, but there is no point in having them fire if we're not building 237# PartitionAlloc at all. If `use_partition_alloc` is false, we jam all 238# related args to `false`. 239if (!use_partition_alloc) { 240 use_partition_alloc_as_malloc = false 241 enable_backup_ref_ptr_support = false 242 use_asan_backup_ref_ptr = false 243 use_asan_unowned_ptr = false 244 use_hookable_raw_ptr = false 245 put_ref_count_in_previous_slot = false 246 enable_backup_ref_ptr_slow_checks = false 247 enable_dangling_raw_ptr_checks = false 248 enable_dangling_raw_ptr_perf_experiment = false 249 enable_pointer_subtraction_check = false 250 backup_ref_ptr_poison_oob_ptr = false 251 use_starscan = false 252} 253 254# put_ref_count_in_previous_slot can only be used if 255# enable_backup_ref_ptr_support is true. 256assert( 257 enable_backup_ref_ptr_support || !put_ref_count_in_previous_slot, 258 "Can't put ref count in the previous slot if BackupRefPtr isn't enabled " + 259 "at all") 260 261# enable_backup_ref_ptr_slow_checks can only be used if 262# enable_backup_ref_ptr_support is true. 263assert(enable_backup_ref_ptr_support || !enable_backup_ref_ptr_slow_checks, 264 "Can't enable additional BackupRefPtr checks if it isn't enabled at all") 265 266# enable_dangling_raw_ptr_checks can only be used if 267# enable_backup_ref_ptr_support is true. 268assert( 269 enable_backup_ref_ptr_support || !enable_dangling_raw_ptr_checks, 270 "Can't enable dangling raw_ptr checks if BackupRefPtr isn't enabled at all") 271 272# To run the dangling raw_ptr detector experiment, the underlying feature must 273# be enabled too. 274assert( 275 enable_dangling_raw_ptr_checks || !enable_dangling_raw_ptr_perf_experiment, 276 "Missing dangling pointer checks feature for its performance experiment") 277 278# To poison OOB pointers for BackupRefPtr, the underlying feature must be 279# enabled, too. 280assert( 281 enable_backup_ref_ptr_support || !backup_ref_ptr_poison_oob_ptr, 282 "Can't enable poisoning for OOB pointers if BackupRefPtr isn't enabled " + 283 "at all") 284assert(has_64_bit_pointers || !backup_ref_ptr_poison_oob_ptr, 285 "Can't enable poisoning for OOB pointers if pointers are only 32-bit") 286 287# AsanBackupRefPtr and AsanUnownedPtr are mutually exclusive variants of 288# raw_ptr. 289assert( 290 !use_asan_unowned_ptr || !use_asan_backup_ref_ptr, 291 "Both AsanUnownedPtr and AsanBackupRefPtr can't be enabled at the same " + 292 "time") 293 294# BackupRefPtr and AsanBackupRefPtr are mutually exclusive variants of raw_ptr. 295assert( 296 !enable_backup_ref_ptr_support || !use_asan_backup_ref_ptr, 297 "Both BackupRefPtr and AsanBackupRefPtr can't be enabled at the same time") 298 299# BackupRefPtr and AsanUnownedPtr are mutually exclusive variants of raw_ptr. 300assert(!enable_backup_ref_ptr_support || !use_asan_unowned_ptr, 301 "Both BackupRefPtr and AsanUnownedPtr can't be enabled at the same time") 302 303# RawPtrHookableImpl and BackupRefPtr are mutually exclusive variants of 304# raw_ptr. 305assert( 306 !use_hookable_raw_ptr || !enable_backup_ref_ptr_support, 307 "Both RawPtrHookableImpl and BackupRefPtr can't be enabled at the same " + 308 "time") 309 310# RawPtrHookableImpl and AsanUnownedPtr are mutually exclusive variants of 311# raw_ptr. 312assert( 313 !use_hookable_raw_ptr || !use_asan_unowned_ptr, 314 "Both RawPtrHookableImpl and AsanUnownedPtr can't be enabled at the same " + 315 "time") 316 317assert(!use_asan_backup_ref_ptr || is_asan, 318 "AsanBackupRefPtr requires AddressSanitizer") 319 320assert(!use_asan_unowned_ptr || is_asan, 321 "AsanUnownedPtr requires AddressSanitizer") 322 323# AsanBackupRefPtr is not supported outside Chromium. The implementation is 324# entangled with `//base`. The code is only physically located with the rest of 325# `raw_ptr` to keep it together. 326assert(build_with_chromium || !use_asan_backup_ref_ptr, 327 "AsanBackupRefPtr is not supported outside Chromium") 328 329assert(!use_asan_backup_ref_ptr || use_hookable_raw_ptr, 330 "AsanBackupRefPtr requires RawPtrHookableImpl") 331 332declare_args() { 333 # pkeys support is explicitly disabled in all Cronet builds, as some test 334 # dependencies that use partition_allocator are compiled in AOSP against a 335 # version of glibc that does not include pkeys syscall numbers. 336 enable_pkeys = is_linux && target_cpu == "x64" && !is_cronet_build 337} 338assert(!enable_pkeys || (is_linux && target_cpu == "x64"), 339 "Pkeys are only supported on x64 linux") 340 341# Some implementations of raw_ptr<>, like BackupRefPtr, require zeroing when 342# constructing, destructing or moving out of a pointer. When using these 343# implementations, raw_ptrs<> will be always be zeroed, no matter what 344# GN args or flags are present. 345# 346# Other implementations of raw_ptr<>, like NoOpImpl, don't require zeroing 347# and do not do so by default. This can lead to subtle bugs when testing 348# against one of the zeroing impls and then deploying on a platform that is 349# using a non-zeroing implementation. Setting the following GN args to 350# true triggers zeroing even for implementations that don't require it. 351# This provides consistency with the other impls. This is the recommended 352# setting. 353# 354# Setting these to false will make raw_ptr<> behave more like raw C++ pointer 355# `T*`, making NoOpImpl act like an actual no-op, so use it if you're worried 356# about performance of your project. Use at your own risk, as it's unsupported 357# and untested within Chromium. 358# 359# Even when these are set to true, the raw_ptr trait AllowUninitialized 360# provides a finer-grained mechanism for opting out of initialization on a 361# pointer by pointer basis when using a non-zeroing implementation. 362# 363# Caveat: _zero_on_move and _on_destruct will prevent the type from being 364# trivially copyable, _zero_on_construct and _on_destruct will prevent the 365# type from being trivially default constructible. 366declare_args() { 367 raw_ptr_zero_on_construct = raw_ptr_zero_on_construct_default 368 raw_ptr_zero_on_move = raw_ptr_zero_on_move_default 369 raw_ptr_zero_on_destruct = raw_ptr_zero_on_destruct_default 370} 371