# 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("//base/allocator/partition_allocator/partition_alloc.gni") import("//build/buildflag_header.gni") import("//build/config/chromecast_build.gni") import("//build/config/chromeos/ui_mode.gni") import("//build/config/dcheck_always_on.gni") import("//build/config/logging.gni") # Add partition_alloc.gni and import it for partition_alloc configs. config("partition_alloc_implementation") { # See also: `partition_alloc_base/component_export.h` defines = [ "IS_PARTITION_ALLOC_IMPL" ] } config("memory_tagging") { if (current_cpu == "arm64" && is_clang && (is_linux || is_chromeos || is_android || is_fuchsia)) { # base/ has access to the MTE intrinsics because it needs to use them, # but they're not backwards compatible. Use base::CPU::has_mte() # beforehand to confirm or use indirect functions (ifuncs) to select # an MTE-specific implementation at dynamic link-time. cflags = [ "-Xclang", "-target-feature", "-Xclang", "+mte", ] } } if (is_fuchsia) { config("fuchsia_sync_lib") { libs = [ "sync", # Used by spinning_mutex.h. ] } } if (enable_pkeys && is_debug) { config("no_stack_protector") { cflags = [ "-fno-stack-protector" ] } } component("partition_alloc") { sources = [ "address_pool_manager.cc", "address_pool_manager.h", "address_pool_manager_bitmap.cc", "address_pool_manager_bitmap.h", "address_pool_manager_types.h", "address_space_randomization.cc", "address_space_randomization.h", "address_space_stats.h", "allocation_guard.cc", "allocation_guard.h", "compressed_pointer.cc", "compressed_pointer.h", "dangling_raw_ptr_checks.cc", "dangling_raw_ptr_checks.h", "freeslot_bitmap.h", "freeslot_bitmap_constants.h", "gwp_asan_support.cc", "gwp_asan_support.h", "memory_reclaimer.cc", "memory_reclaimer.h", "oom.cc", "oom.h", "oom_callback.cc", "oom_callback.h", "page_allocator.cc", "page_allocator.h", "page_allocator_constants.h", "page_allocator_internal.h", "partition_address_space.cc", "partition_address_space.h", "partition_alloc-inl.h", "partition_alloc.cc", "partition_alloc.h", "partition_alloc_base/atomic_ref_count.h", "partition_alloc_base/augmentations/compiler_specific.h", "partition_alloc_base/bit_cast.h", "partition_alloc_base/bits.h", "partition_alloc_base/check.cc", "partition_alloc_base/check.h", "partition_alloc_base/compiler_specific.h", "partition_alloc_base/component_export.h", "partition_alloc_base/cpu.cc", "partition_alloc_base/cpu.h", "partition_alloc_base/cxx17_backports.h", "partition_alloc_base/cxx20_is_constant_evaluated.h", "partition_alloc_base/debug/alias.cc", "partition_alloc_base/debug/alias.h", "partition_alloc_base/gtest_prod_util.h", "partition_alloc_base/immediate_crash.h", "partition_alloc_base/logging.cc", "partition_alloc_base/logging.h", "partition_alloc_base/memory/ref_counted.cc", "partition_alloc_base/memory/ref_counted.h", "partition_alloc_base/memory/scoped_policy.h", "partition_alloc_base/memory/scoped_refptr.h", "partition_alloc_base/no_destructor.h", "partition_alloc_base/numerics/checked_math.h", "partition_alloc_base/numerics/checked_math_impl.h", "partition_alloc_base/numerics/clamped_math.h", "partition_alloc_base/numerics/clamped_math_impl.h", "partition_alloc_base/numerics/math_constants.h", "partition_alloc_base/numerics/ostream_operators.h", "partition_alloc_base/numerics/ranges.h", "partition_alloc_base/numerics/safe_conversions.h", "partition_alloc_base/numerics/safe_conversions_arm_impl.h", "partition_alloc_base/numerics/safe_conversions_impl.h", "partition_alloc_base/numerics/safe_math.h", "partition_alloc_base/numerics/safe_math_arm_impl.h", "partition_alloc_base/numerics/safe_math_clang_gcc_impl.h", "partition_alloc_base/numerics/safe_math_shared_impl.h", "partition_alloc_base/posix/eintr_wrapper.h", "partition_alloc_base/rand_util.cc", "partition_alloc_base/rand_util.h", "partition_alloc_base/scoped_clear_last_error.h", "partition_alloc_base/strings/stringprintf.cc", "partition_alloc_base/strings/stringprintf.h", "partition_alloc_base/system/sys_info.h", "partition_alloc_base/thread_annotations.h", "partition_alloc_base/threading/platform_thread.cc", "partition_alloc_base/threading/platform_thread.h", "partition_alloc_base/threading/platform_thread_ref.h", "partition_alloc_base/time/time.cc", "partition_alloc_base/time/time.h", "partition_alloc_base/time/time_override.cc", "partition_alloc_base/time/time_override.h", "partition_alloc_base/types/strong_alias.h", "partition_alloc_base/win/win_handle_types.h", "partition_alloc_base/win/win_handle_types_list.inc", "partition_alloc_base/win/windows_types.h", "partition_alloc_check.h", "partition_alloc_config.h", "partition_alloc_constants.h", "partition_alloc_forward.h", "partition_alloc_hooks.cc", "partition_alloc_hooks.h", "partition_alloc_notreached.h", "partition_bucket.cc", "partition_bucket.h", "partition_bucket_lookup.h", "partition_cookie.h", "partition_direct_map_extent.h", "partition_freelist_entry.h", "partition_lock.h", "partition_oom.cc", "partition_oom.h", "partition_page.cc", "partition_page.h", "partition_ref_count.h", "partition_root.cc", "partition_root.h", "partition_stats.cc", "partition_stats.h", "partition_tls.h", "pkey.cc", "pkey.h", "random.cc", "random.h", "reservation_offset_table.cc", "reservation_offset_table.h", "reverse_bytes.h", "spinning_mutex.cc", "spinning_mutex.h", "tagging.cc", "tagging.h", "thread_cache.cc", "thread_cache.h", "yield_processor.h", ] if (use_starscan) { sources += [ "starscan/logging.h", "starscan/metadata_allocator.cc", "starscan/metadata_allocator.h", "starscan/pcscan.cc", "starscan/pcscan.h", "starscan/pcscan_internal.cc", "starscan/pcscan_internal.h", "starscan/pcscan_scheduling.cc", "starscan/pcscan_scheduling.h", "starscan/raceful_worklist.h", "starscan/scan_loop.h", "starscan/snapshot.cc", "starscan/snapshot.h", "starscan/stack/stack.cc", "starscan/stack/stack.h", "starscan/starscan_fwd.h", "starscan/state_bitmap.h", "starscan/stats_collector.cc", "starscan/stats_collector.h", "starscan/stats_reporter.h", "starscan/write_protector.cc", "starscan/write_protector.h", ] } defines = [] if (is_win) { sources += [ "page_allocator_internals_win.h", "partition_alloc_base/rand_util_win.cc", "partition_alloc_base/scoped_clear_last_error_win.cc", "partition_alloc_base/threading/platform_thread_win.cc", "partition_alloc_base/time/time_win.cc", "partition_tls_win.cc", ] } else if (is_posix) { sources += [ "page_allocator_internals_posix.cc", "page_allocator_internals_posix.h", "partition_alloc_base/files/file_util.h", "partition_alloc_base/files/file_util_posix.cc", "partition_alloc_base/posix/safe_strerror.cc", "partition_alloc_base/posix/safe_strerror.h", "partition_alloc_base/rand_util_posix.cc", "partition_alloc_base/threading/platform_thread_internal_posix.h", "partition_alloc_base/threading/platform_thread_posix.cc", "partition_alloc_base/time/time_conversion_posix.cc", ] if (is_android || is_chromeos_ash) { sources += [ "partition_alloc_base/time/time_android.cc" ] } if (is_apple) { sources += [ "partition_alloc_base/time/time_mac.mm" ] } else { sources += [ "partition_alloc_base/time/time_now_posix.cc" ] } } else if (is_fuchsia) { sources += [ "page_allocator_internals_fuchsia.h", "partition_alloc_base/fuchsia/fuchsia_logging.cc", "partition_alloc_base/fuchsia/fuchsia_logging.h", "partition_alloc_base/posix/safe_strerror.cc", "partition_alloc_base/posix/safe_strerror.h", "partition_alloc_base/rand_util_fuchsia.cc", "partition_alloc_base/threading/platform_thread_internal_posix.h", "partition_alloc_base/threading/platform_thread_posix.cc", "partition_alloc_base/time/time_conversion_posix.cc", "partition_alloc_base/time/time_fuchsia.cc", ] } if (is_android) { # Only android build requires native_library, and native_library depends # on file_path. So file_path is added if is_android = true. sources += [ "partition_alloc_base/files/file_path.cc", "partition_alloc_base/files/file_path.h", "partition_alloc_base/native_library.cc", "partition_alloc_base/native_library.h", "partition_alloc_base/native_library_posix.cc", ] } if (is_apple) { # Apple-specific utilities sources += [ "partition_alloc_base/mac/foundation_util.h", "partition_alloc_base/mac/foundation_util.mm", "partition_alloc_base/mac/scoped_cftyperef.h", "partition_alloc_base/mac/scoped_typeref.h", ] if (is_ios) { sources += [ "partition_alloc_base/ios/ios_util.h", "partition_alloc_base/ios/ios_util.mm", "partition_alloc_base/system/sys_info_ios.mm", ] } if (is_mac) { sources += [ "partition_alloc_base/mac/mac_util.h", "partition_alloc_base/mac/mac_util.mm", "partition_alloc_base/system/sys_info_mac.mm", ] } } if (use_starscan) { if (current_cpu == "x64") { assert(pcscan_stack_supported) sources += [ "starscan/stack/asm/x64/push_registers_asm.cc" ] } else if (current_cpu == "x86") { assert(pcscan_stack_supported) sources += [ "starscan/stack/asm/x86/push_registers_asm.cc" ] } else if (current_cpu == "arm") { assert(pcscan_stack_supported) sources += [ "starscan/stack/asm/arm/push_registers_asm.cc" ] } else if (current_cpu == "arm64") { assert(pcscan_stack_supported) sources += [ "starscan/stack/asm/arm64/push_registers_asm.cc" ] } else { # To support a trampoline for another arch, please refer to v8/src/heap/base. assert(!pcscan_stack_supported) } } public_deps = [ ":chromecast_buildflags", ":chromeos_buildflags", ":debugging_buildflags", ":logging_buildflags", ":partition_alloc_buildflags", ] configs += [ ":partition_alloc_implementation", ":memory_tagging", ] deps = [] public_configs = [] if (is_android) { # tagging.cc requires __arm_mte_set_* functions. deps += [ "//third_party/android_ndk:cpu_features" ] } if (is_fuchsia) { public_deps += [ "//third_party/fuchsia-sdk/sdk/pkg/fit", "//third_party/fuchsia-sdk/sdk/pkg/sync", "//third_party/fuchsia-sdk/sdk/pkg/zx", ] # Needed for users of spinning_mutex.h, which for performance reasons, # contains inlined calls to `libsync` inside the header file. # It appends an entry to the "libs" section of the dependent target. public_configs += [ ":fuchsia_sync_lib" ] } frameworks = [] if (is_mac) { # SecTaskGetCodeSignStatus needs: frameworks += [ "Security.framework" ] } if (is_apple) { frameworks += [ "CoreFoundation.framework", "Foundation.framework", ] } configs += [ "//build/config/compiler:wexit_time_destructors" ] # Partition alloc is relatively hot (>1% of cycles for users of CrOS). Use speed-focused # optimizations for it. if (!is_debug) { configs -= [ "//build/config/compiler:default_optimization" ] configs += [ "//build/config/compiler:optimize_speed" ] } # We want to be able to test pkey mode without access to the default pkey. # This is incompatible with stack protectors since the TLS won't be pkey-tagged. if (enable_pkeys && is_debug) { configs += [ ":no_stack_protector" ] } } source_set("raw_ptr") { # `gn check` is unhappy with most `#includes` when PA isn't # actually built. check_includes = use_partition_alloc public = [ "pointers/raw_ptr.h", "pointers/raw_ptr_exclusion.h", "pointers/raw_ref.h", ] sources = [] if (enable_backup_ref_ptr_support) { sources += [ "pointers/raw_ptr_backup_ref_impl.cc", "pointers/raw_ptr_backup_ref_impl.h", ] } else if (use_hookable_raw_ptr) { sources += [ "pointers/raw_ptr_hookable_impl.cc", "pointers/raw_ptr_hookable_impl.h", ] } else if (use_asan_unowned_ptr) { sources += [ "pointers/raw_ptr_asan_unowned_impl.cc", "pointers/raw_ptr_asan_unowned_impl.h", ] } if (use_partition_alloc) { public_deps = [ ":partition_alloc" ] } deps = [ ":buildflags" ] # See also: `partition_alloc_base/component_export.h` defines = [ "IS_RAW_PTR_IMPL" ] # When built inside Chromium, although this cannot directly be made a # component, we expect `//base` to provide the only GN-level access. if (build_with_chromium) { visibility = [ "//base" ] } } buildflag_header("partition_alloc_buildflags") { header = "partition_alloc_buildflags.h" _record_alloc_info = false # GWP-ASan is tied to BRP's "refcount in previous slot" mode, whose # enablement is already gated on BRP enablement. _enable_gwp_asan_support = put_ref_count_in_previous_slot # TODO(crbug.com/1151236): Need to refactor the following buildflags. # The buildflags (except RECORD_ALLOC_INFO) are used by both chrome and # partition alloc. For partition alloc, # gen/base/allocator/partition_allocator/partition_alloc_buildflags.h # defines and partition alloc includes the header file. For chrome, # gen/base/allocator/buildflags.h defines and chrome includes. flags = [ "HAS_64_BIT_POINTERS=$has_64_bit_pointers", "USE_PARTITION_ALLOC=$use_partition_alloc", "USE_PARTITION_ALLOC_AS_MALLOC=$use_partition_alloc_as_malloc", "ENABLE_BACKUP_REF_PTR_SUPPORT=$enable_backup_ref_ptr_support", "ENABLE_BACKUP_REF_PTR_SLOW_CHECKS=$enable_backup_ref_ptr_slow_checks", "ENABLE_BACKUP_REF_PTR_FEATURE_FLAG=$enable_backup_ref_ptr_feature_flag", "ENABLE_RAW_PTR_EXPERIMENTAL=$enable_raw_ptr_experimental", "ENABLE_DANGLING_RAW_PTR_CHECKS=$enable_dangling_raw_ptr_checks", "ENABLE_DANGLING_RAW_PTR_FEATURE_FLAG=$enable_dangling_raw_ptr_feature_flag", "ENABLE_DANGLING_RAW_PTR_PERF_EXPERIMENT=$enable_dangling_raw_ptr_perf_experiment", "ENABLE_POINTER_SUBTRACTION_CHECK=$enable_pointer_subtraction_check", "BACKUP_REF_PTR_POISON_OOB_PTR=$backup_ref_ptr_poison_oob_ptr", "PUT_REF_COUNT_IN_PREVIOUS_SLOT=$put_ref_count_in_previous_slot", "USE_ASAN_BACKUP_REF_PTR=$use_asan_backup_ref_ptr", "USE_ASAN_UNOWNED_PTR=$use_asan_unowned_ptr", "USE_HOOKABLE_RAW_PTR=$use_hookable_raw_ptr", "ENABLE_GWP_ASAN_SUPPORT=$_enable_gwp_asan_support", "FORCE_ENABLE_RAW_PTR_EXCLUSION=$force_enable_raw_ptr_exclusion", "RECORD_ALLOC_INFO=$_record_alloc_info", "USE_FREESLOT_BITMAP=$use_freeslot_bitmap", "GLUE_CORE_POOLS=$glue_core_pools", "ENABLE_POINTER_COMPRESSION=$enable_pointer_compression_support", "ENABLE_SHADOW_METADATA_FOR_64_BITS_POINTERS=$enable_shadow_metadata", "USE_STARSCAN=$use_starscan", "PCSCAN_STACK_SUPPORTED=$pcscan_stack_supported", "ENABLE_PKEYS=$enable_pkeys", ] if (is_apple) { # TODO(crbug.com/1414153): once TimeTicks::Now behavior is unified on iOS, # this should be removed. flags += [ "PARTITION_ALLOC_ENABLE_MACH_ABSOLUTE_TIME_TICKS=" + "$partition_alloc_enable_mach_absolute_time_ticks" ] } } buildflag_header("chromecast_buildflags") { header = "chromecast_buildflags.h" flags = [ "PA_IS_CAST_ANDROID=$is_cast_android", "PA_IS_CASTOS=$is_castos", ] } buildflag_header("chromeos_buildflags") { header = "chromeos_buildflags.h" flags = [ "PA_IS_CHROMEOS_ASH=$is_chromeos_ash" ] } buildflag_header("logging_buildflags") { header = "logging_buildflags.h" flags = [ "PA_ENABLE_LOG_ERROR_NOT_REACHED=$enable_log_error_not_reached" ] } buildflag_header("debugging_buildflags") { header = "debugging_buildflags.h" header_dir = rebase_path(".", "//") + "/partition_alloc_base/debug" # Duplicates the setup Chromium uses to define `DCHECK_IS_ON()`, # but avails it as a buildflag. _dcheck_is_on = is_debug || dcheck_always_on flags = [ "PA_DCHECK_IS_ON=$_dcheck_is_on", "PA_EXPENSIVE_DCHECKS_ARE_ON=$enable_expensive_dchecks", "PA_DCHECK_IS_CONFIGURABLE=$dcheck_is_configurable", ] } group("buildflags") { public_deps = [ ":chromecast_buildflags", ":chromeos_buildflags", ":debugging_buildflags", ":logging_buildflags", ":partition_alloc_buildflags", ] } # TODO(crbug.com/1151236): After making partition_alloc a standalone library, # move test code here. i.e. test("partition_alloc_tests") { ... } and # test("partition_alloc_perftests").