blob: 447fe26d52a6c1f4affa2623a9ea0a28a5cb6768 [file] [log] [blame]
# 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
}