| # Copyright 2022 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//build/config/cronet/config.gni") |
| import("//build/config/sanitizers/sanitizers.gni") |
| import("//build_overrides/partition_alloc.gni") |
| |
| if (is_apple) { |
| import("//build/config/features.gni") |
| } |
| |
| # PartitionAlloc have limited support for MSVC's cl.exe compiler. It can only |
| # access the generate "buildflags" and the "raw_ptr" definitions implemented |
| # with RawPtrNoOpImpl. Everything else is considered not supported. |
| # |
| # Since there are no other good ways to detect MSVC's cl.exe, we are reusing the |
| # same definition used by Chrome in //base/BUILD.gn. See |
| # https://crbug.com/988071. |
| is_clang_or_gcc = is_clang || !is_win |
| |
| # Whether 64-bit pointers are used. |
| # A static_assert in partition_alloc_config.h verifies that. |
| if (is_nacl) { |
| # NaCl targets don't use 64-bit pointers. |
| has_64_bit_pointers = false |
| } else if (current_cpu == "x64" || current_cpu == "arm64" || |
| current_cpu == "loong64" || current_cpu == "riscv64") { |
| has_64_bit_pointers = true |
| } else if (current_cpu == "x86" || current_cpu == "arm") { |
| has_64_bit_pointers = false |
| } else { |
| assert(false, "Unknown CPU: $current_cpu") |
| } |
| |
| declare_args() { |
| # Causes all the allocations to be routed via allocator_shim.cc. Usually, |
| # the allocator shim will, in turn, route them to Partition Alloc, but |
| # other allocators are also supported by the allocator shim. |
| use_allocator_shim = use_allocator_shim_default && is_clang_or_gcc |
| |
| # Whether PartitionAlloc should be available for use or not. |
| # true makes PartitionAlloc linked to the executable or shared library and |
| # makes it available for use. It doesn't mean that the default allocator |
| # is PartitionAlloc, which is governed by |use_partition_alloc_as_malloc|. |
| # |
| # N.B. generally, embedders should look at this GN arg and at the |
| # corresponding buildflag to determine whether to interact with PA |
| # source at all (pulling the component in via GN, including headers, |
| # etc.). There is nothing stopping a lazy embedder from ignoring this |
| # and unconditionally using PA, but such a setup is inadvisable. |
| # |
| # In Chromium, this is set true, except: |
| # |
| # 1. On Cronet bots, because Cronet doesn't use PartitionAlloc at all, |
| # and doesn't wish to incur the library size increase (crbug.com/674570). |
| # 2. On NaCl (through this declaration), where PartitionAlloc doesn't |
| # build at all. |
| use_partition_alloc = !is_nacl && is_clang_or_gcc |
| } |
| |
| if (!is_clang_or_gcc) { |
| assert(!use_partition_alloc, |
| "PartitionAlloc's allocator does not support this compiler") |
| assert(!use_allocator_shim, |
| "PartitionAlloc's allocator shim does not support this compiler") |
| } |
| |
| if (is_nacl) { |
| assert(!use_partition_alloc, "PartitionAlloc doesn't build on NaCl") |
| } |
| |
| declare_args() { |
| # Turns on compiler optimizations in PartitionAlloc in Debug build. |
| # If enabling PartitionAlloc-Everywhere in Debug build for tests in Debug |
| # build, since all memory allocations and deallocations are executed by |
| # non-optimized PartitionAlloc, chrome (including tests) will be much |
| # slower. This will cause debug trybots' timeouts. If we want to debug |
| # PartitionAlloc itself, use partition_alloc_optimized_debug=false. |
| # Otherwise, use partition_alloc_optimized_debug=true to enable optimized |
| # PartitionAlloc. |
| partition_alloc_optimized_debug = true |
| |
| # PartitionAlloc-Everywhere (PA-E). Causes allocator_shim.cc to route |
| # calls to PartitionAlloc, rather than some other platform allocator. |
| use_partition_alloc_as_malloc = use_partition_alloc && use_allocator_shim && |
| use_partition_alloc_as_malloc_default |
| } |
| |
| assert(!use_allocator_shim || (is_android || is_apple || is_chromeos || |
| is_fuchsia || is_linux || is_win), |
| "The allocator shim does not (yet) support the platform.") |
| |
| if (use_allocator_shim && is_win) { |
| # It's hard to override CRT's malloc family in every case in the component |
| # build, and it's very easy to override it partially and to be inconsistent |
| # among allocations and deallocations. Then, we'll crash when PA deallocates |
| # a memory region allocated by the CRT's malloc or vice versa. |
| assert(!is_component_build, |
| "The allocator shim doesn't work for the component build on Windows.") |
| } |
| |
| declare_args() { |
| use_freeslot_bitmap = false |
| |
| # Puts the regular and BRP pools right next to each other, so that we can |
| # check "belongs to one of the two pools" with a single bitmask operation. |
| glue_core_pools = false |
| |
| # Introduces pointer compression support in PA. These are 4-byte |
| # pointers that can point within the core pools (regular and BRP). |
| # |
| # This is effective only for memory allocated from PartitionAlloc, so it is |
| # recommended to enable PA-E above, but isn't strictly necessary. Embedders |
| # can create and use PA partitions explicitly. |
| enable_pointer_compression_support = false |
| |
| # Enables a bounds check when two pointers (at least one being raw_ptr) are |
| # subtracted (if supported by the underlying implementation). |
| enable_pointer_subtraction_check = false |
| |
| # Enables a compile-time check that all raw_ptrs to which arithmetic |
| # operations are to be applied are annotated with the AllowPtrArithmetic |
| # trait, |
| enable_pointer_arithmetic_trait_check = true |
| } |
| |
| declare_args() { |
| # Build support for Use-after-Free protection via BackupRefPtr (BRP), |
| # making the raw_ptr<T> implementation to RawPtrBackupRefImpl if active. |
| # |
| # These are effective only for memory allocated from PartitionAlloc, so it is |
| # recommended to enable PA-E above, but isn't strictly necessary. Embedders |
| # can create and use PA partitions explicitly. |
| # |
| # Note that |enable_backup_ref_ptr_support = true| doesn't necessarily enable |
| # BRP protection. It'll be enabled only for partition created with |
| # partition_alloc::PartitionOptions::kEnabled. |
| enable_backup_ref_ptr_support = |
| use_partition_alloc && enable_backup_ref_ptr_support_default |
| |
| # RAW_PTR_EXCLUSION macro is disabled on official builds because it increased |
| # binary size. This flag can be used to enable it for official builds too. |
| force_enable_raw_ptr_exclusion = false |
| } |
| |
| assert(!enable_pointer_compression_support || glue_core_pools, |
| "Pointer compression relies on core pools being contiguous.") |
| |
| declare_args() { |
| # Make explicit calls to ASAN at runtime, e.g. to mark quarrantined memory |
| # as poisoned. Allows ASAN to tell if a particular memory error is protected |
| # by BRP in its reports. |
| # |
| # The implementation of ASan BRP is purpose-built to inspect Chromium |
| # internals and is entangled with `//base` s.t. it cannot be used |
| # outside of Chromium. |
| use_asan_backup_ref_ptr = |
| build_with_chromium && is_asan && |
| (is_win || is_android || is_linux || is_mac || is_chromeos) |
| |
| # Use probe-on-destruct unowned ptr detection with ASAN. |
| use_asan_unowned_ptr = false |
| } |
| |
| # Use the version of raw_ptr<T> that allows the embedder to implement custom |
| # logic. |
| use_hookable_raw_ptr = use_asan_backup_ref_ptr |
| |
| declare_args() { |
| # - put_ref_count_in_previous_slot: place the ref-count at the end of the |
| # previous slot (or in metadata if a slot starts on the page boundary), as |
| # opposed to the beginning of the slot. |
| # - enable_backup_ref_ptr_slow_checks: enable additional safety checks that |
| # are too expensive to have on by default. |
| # - enable_dangling_raw_ptr_checks: enable checking raw_ptr do not become |
| # dangling during their lifetime. |
| # - backup_ref_ptr_poison_oob_ptr: poison out-of-bounds (OOB) pointers to |
| # generate an exception in the event that an OOB pointer is dereferenced. |
| put_ref_count_in_previous_slot = |
| put_ref_count_in_previous_slot_default && enable_backup_ref_ptr_support |
| |
| enable_backup_ref_ptr_slow_checks = |
| enable_backup_ref_ptr_slow_checks_default && enable_backup_ref_ptr_support |
| |
| # Enable the feature flag required to activate backup ref pointers. That is to |
| # say `PartitionAllocBackupRefPtr`. |
| # |
| # This is meant to be used primarily on bots. It is much easier to override |
| # the feature flags using a binary flag instead of updating multiple bots's |
| # scripts to pass command line arguments. |
| enable_backup_ref_ptr_feature_flag = false |
| |
| # Build support for Dangling Ptr Detection (DPD) via BackupRefPtr (BRP), |
| # making the raw_ptr<T> implementation to RawPtrBackupRefImpl if active. |
| enable_dangling_raw_ptr_checks = |
| enable_dangling_raw_ptr_checks_default && enable_backup_ref_ptr_support |
| |
| # Enable the feature flag required to check for dangling pointers. That is to |
| # say `PartitionAllocDanglingPtr`. |
| # |
| # This is meant to be used primarily on bots. It is much easier to override |
| # the feature flags using a binary flag instead of updating multiple bots's |
| # scripts to pass command line arguments. |
| enable_dangling_raw_ptr_feature_flag = false |
| |
| # Enables the dangling raw_ptr checks feature for the performance experiment. |
| # Not every dangling pointers have been fixed or annotated yet. To avoid |
| # accounting for the cost of calling the PA's embedder's callbacks when a |
| # dangling pointer has been detected, this simulates the raw_ptr to be |
| # allowed to dangle. |
| # |
| # This flag is temporary, and isn't used by PA embedders, so it doesn't need |
| # to go through build_overrides |
| enable_dangling_raw_ptr_perf_experiment = false |
| |
| # Set to `enable_backup_ref_ptr_support && has_64_bit_pointers` when enabling. |
| backup_ref_ptr_poison_oob_ptr = false |
| } |
| |
| declare_args() { |
| # Shadow metadata is still under development and only supports Linux |
| # for now. |
| enable_shadow_metadata = false |
| } |
| |
| # *Scan is currently only used by Chromium, and supports only 64-bit. |
| use_starscan = build_with_chromium && has_64_bit_pointers |
| |
| pcscan_stack_supported = |
| use_starscan && |
| (current_cpu == "x64" || current_cpu == "x86" || current_cpu == "arm" || |
| current_cpu == "arm64" || current_cpu == "riscv64") |
| |
| # We want to provide assertions that guard against inconsistent build |
| # args, but there is no point in having them fire if we're not building |
| # PartitionAlloc at all. If `use_partition_alloc` is false, we jam all |
| # related args to `false`. |
| if (!use_partition_alloc) { |
| use_partition_alloc_as_malloc = false |
| enable_backup_ref_ptr_support = false |
| use_asan_backup_ref_ptr = false |
| use_asan_unowned_ptr = false |
| use_hookable_raw_ptr = false |
| put_ref_count_in_previous_slot = false |
| enable_backup_ref_ptr_slow_checks = false |
| enable_dangling_raw_ptr_checks = false |
| enable_dangling_raw_ptr_perf_experiment = false |
| enable_pointer_subtraction_check = false |
| backup_ref_ptr_poison_oob_ptr = false |
| use_starscan = false |
| } |
| |
| # put_ref_count_in_previous_slot can only be used if |
| # enable_backup_ref_ptr_support is true. |
| assert( |
| enable_backup_ref_ptr_support || !put_ref_count_in_previous_slot, |
| "Can't put ref count in the previous slot if BackupRefPtr isn't enabled " + |
| "at all") |
| |
| # enable_backup_ref_ptr_slow_checks can only be used if |
| # enable_backup_ref_ptr_support is true. |
| assert(enable_backup_ref_ptr_support || !enable_backup_ref_ptr_slow_checks, |
| "Can't enable additional BackupRefPtr checks if it isn't enabled at all") |
| |
| # enable_dangling_raw_ptr_checks can only be used if |
| # enable_backup_ref_ptr_support is true. |
| assert( |
| enable_backup_ref_ptr_support || !enable_dangling_raw_ptr_checks, |
| "Can't enable dangling raw_ptr checks if BackupRefPtr isn't enabled at all") |
| |
| # To run the dangling raw_ptr detector experiment, the underlying feature must |
| # be enabled too. |
| assert( |
| enable_dangling_raw_ptr_checks || !enable_dangling_raw_ptr_perf_experiment, |
| "Missing dangling pointer checks feature for its performance experiment") |
| |
| # To poison OOB pointers for BackupRefPtr, the underlying feature must be |
| # enabled, too. |
| assert( |
| enable_backup_ref_ptr_support || !backup_ref_ptr_poison_oob_ptr, |
| "Can't enable poisoning for OOB pointers if BackupRefPtr isn't enabled " + |
| "at all") |
| assert(has_64_bit_pointers || !backup_ref_ptr_poison_oob_ptr, |
| "Can't enable poisoning for OOB pointers if pointers are only 32-bit") |
| |
| # AsanBackupRefPtr and AsanUnownedPtr are mutually exclusive variants of |
| # raw_ptr. |
| assert( |
| !use_asan_unowned_ptr || !use_asan_backup_ref_ptr, |
| "Both AsanUnownedPtr and AsanBackupRefPtr can't be enabled at the same " + |
| "time") |
| |
| # BackupRefPtr and AsanBackupRefPtr are mutually exclusive variants of raw_ptr. |
| assert( |
| !enable_backup_ref_ptr_support || !use_asan_backup_ref_ptr, |
| "Both BackupRefPtr and AsanBackupRefPtr can't be enabled at the same time") |
| |
| # BackupRefPtr and AsanUnownedPtr are mutually exclusive variants of raw_ptr. |
| assert(!enable_backup_ref_ptr_support || !use_asan_unowned_ptr, |
| "Both BackupRefPtr and AsanUnownedPtr can't be enabled at the same time") |
| |
| # RawPtrHookableImpl and BackupRefPtr are mutually exclusive variants of |
| # raw_ptr. |
| assert( |
| !use_hookable_raw_ptr || !enable_backup_ref_ptr_support, |
| "Both RawPtrHookableImpl and BackupRefPtr can't be enabled at the same " + |
| "time") |
| |
| # RawPtrHookableImpl and AsanUnownedPtr are mutually exclusive variants of |
| # raw_ptr. |
| assert( |
| !use_hookable_raw_ptr || !use_asan_unowned_ptr, |
| "Both RawPtrHookableImpl and AsanUnownedPtr can't be enabled at the same " + |
| "time") |
| |
| assert(!use_asan_backup_ref_ptr || is_asan, |
| "AsanBackupRefPtr requires AddressSanitizer") |
| |
| assert(!use_asan_unowned_ptr || is_asan, |
| "AsanUnownedPtr requires AddressSanitizer") |
| |
| # AsanBackupRefPtr is not supported outside Chromium. The implementation is |
| # entangled with `//base`. The code is only physically located with the rest of |
| # `raw_ptr` to keep it together. |
| assert(build_with_chromium || !use_asan_backup_ref_ptr, |
| "AsanBackupRefPtr is not supported outside Chromium") |
| |
| assert(!use_asan_backup_ref_ptr || use_hookable_raw_ptr, |
| "AsanBackupRefPtr requires RawPtrHookableImpl") |
| |
| declare_args() { |
| # pkeys support is explicitly disabled in all Cronet builds, as some test |
| # dependencies that use partition_allocator are compiled in AOSP against a |
| # version of glibc that does not include pkeys syscall numbers. |
| enable_pkeys = is_linux && target_cpu == "x64" && !is_cronet_build |
| } |
| assert(!enable_pkeys || (is_linux && target_cpu == "x64"), |
| "Pkeys are only supported on x64 linux") |
| |
| # Some implementations of raw_ptr<>, like BackupRefPtr, require zeroing when |
| # constructing, destructing or moving out of a pointer. When using these |
| # implementations, raw_ptrs<> will be always be zeroed, no matter what |
| # GN args or flags are present. |
| # |
| # Other implementations of raw_ptr<>, like NoOpImpl, don't require zeroing |
| # and do not do so by default. This can lead to subtle bugs when testing |
| # against one of the zeroing impls and then deploying on a platform that is |
| # using a non-zeroing implementation. Setting the following GN args to |
| # true triggers zeroing even for implementations that don't require it. |
| # This provides consistency with the other impls. This is the recommended |
| # setting. |
| # |
| # Setting these to false will make raw_ptr<> behave more like raw C++ pointer |
| # `T*`, making NoOpImpl act like an actual no-op, so use it if you're worried |
| # about performance of your project. Use at your own risk, as it's unsupported |
| # and untested within Chromium. |
| # |
| # Even when these are set to true, the raw_ptr trait AllowUninitialized |
| # provides a finer-grained mechanism for opting out of initialization on a |
| # pointer by pointer basis when using a non-zeroing implementation. |
| # |
| # Caveat: _zero_on_move and _on_destruct will prevent the type from being |
| # trivially copyable, _zero_on_construct and _on_destruct will prevent the |
| # type from being trivially default constructible. |
| declare_args() { |
| raw_ptr_zero_on_construct = raw_ptr_zero_on_construct_default |
| raw_ptr_zero_on_move = raw_ptr_zero_on_move_default |
| raw_ptr_zero_on_destruct = raw_ptr_zero_on_destruct_default |
| } |