1*2dc9ec47SChiaHungDuan //===-- allocator_config_test.cpp -------------------------------*- C++ -*-===// 2*2dc9ec47SChiaHungDuan // 3*2dc9ec47SChiaHungDuan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2dc9ec47SChiaHungDuan // See https://llvm.org/LICENSE.txt for license information. 5*2dc9ec47SChiaHungDuan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*2dc9ec47SChiaHungDuan // 7*2dc9ec47SChiaHungDuan //===----------------------------------------------------------------------===// 8*2dc9ec47SChiaHungDuan 9*2dc9ec47SChiaHungDuan #include "tests/scudo_unit_test.h" 10*2dc9ec47SChiaHungDuan 11*2dc9ec47SChiaHungDuan #include "allocator_config.h" 12*2dc9ec47SChiaHungDuan #include "allocator_config_wrapper.h" 13*2dc9ec47SChiaHungDuan #include "common.h" 14*2dc9ec47SChiaHungDuan #include "secondary.h" 15*2dc9ec47SChiaHungDuan 16*2dc9ec47SChiaHungDuan #include <type_traits> 17*2dc9ec47SChiaHungDuan 18*2dc9ec47SChiaHungDuan struct TestBaseConfig { 19*2dc9ec47SChiaHungDuan template <typename> using TSDRegistryT = void; 20*2dc9ec47SChiaHungDuan template <typename> using PrimaryT = void; 21*2dc9ec47SChiaHungDuan template <typename> using SecondaryT = void; 22*2dc9ec47SChiaHungDuan }; 23*2dc9ec47SChiaHungDuan 24*2dc9ec47SChiaHungDuan struct TestBaseConfigEnableOptionalFlag : public TestBaseConfig { 25*2dc9ec47SChiaHungDuan static const bool MaySupportMemoryTagging = true; 26*2dc9ec47SChiaHungDuan // Use the getter to avoid the test to `use` the address of static const 27*2dc9ec47SChiaHungDuan // variable (which requires additional explicit definition). getMaySupportMemoryTaggingTestBaseConfigEnableOptionalFlag28*2dc9ec47SChiaHungDuan static bool getMaySupportMemoryTagging() { return MaySupportMemoryTagging; } 29*2dc9ec47SChiaHungDuan }; 30*2dc9ec47SChiaHungDuan 31*2dc9ec47SChiaHungDuan struct TestBasePrimaryConfig { 32*2dc9ec47SChiaHungDuan using SizeClassMap = void; 33*2dc9ec47SChiaHungDuan static const scudo::uptr RegionSizeLog = 18U; 34*2dc9ec47SChiaHungDuan static const scudo::uptr GroupSizeLog = 18U; 35*2dc9ec47SChiaHungDuan static const scudo::s32 MinReleaseToOsIntervalMs = INT32_MIN; 36*2dc9ec47SChiaHungDuan static const scudo::s32 MaxReleaseToOsIntervalMs = INT32_MAX; 37*2dc9ec47SChiaHungDuan typedef scudo::uptr CompactPtrT; 38*2dc9ec47SChiaHungDuan static const scudo::uptr CompactPtrScale = 0; 39*2dc9ec47SChiaHungDuan static const scudo::uptr MapSizeIncrement = 1UL << 18; 40*2dc9ec47SChiaHungDuan }; 41*2dc9ec47SChiaHungDuan 42*2dc9ec47SChiaHungDuan struct TestPrimaryConfig : public TestBaseConfig { 43*2dc9ec47SChiaHungDuan struct Primary : TestBasePrimaryConfig {}; 44*2dc9ec47SChiaHungDuan }; 45*2dc9ec47SChiaHungDuan 46*2dc9ec47SChiaHungDuan struct TestPrimaryConfigEnableOptionalFlag : public TestBaseConfig { 47*2dc9ec47SChiaHungDuan struct Primary : TestBasePrimaryConfig { 48*2dc9ec47SChiaHungDuan static const bool EnableRandomOffset = true; getEnableRandomOffsetTestPrimaryConfigEnableOptionalFlag::Primary49*2dc9ec47SChiaHungDuan static bool getEnableRandomOffset() { return EnableRandomOffset; } 50*2dc9ec47SChiaHungDuan }; 51*2dc9ec47SChiaHungDuan }; 52*2dc9ec47SChiaHungDuan 53*2dc9ec47SChiaHungDuan struct TestPrimaryConfigEnableOptionalType : public TestBaseConfig { 54*2dc9ec47SChiaHungDuan struct DummyConditionVariable {}; 55*2dc9ec47SChiaHungDuan 56*2dc9ec47SChiaHungDuan struct Primary : TestBasePrimaryConfig { 57*2dc9ec47SChiaHungDuan using ConditionVariableT = DummyConditionVariable; 58*2dc9ec47SChiaHungDuan }; 59*2dc9ec47SChiaHungDuan }; 60*2dc9ec47SChiaHungDuan 61*2dc9ec47SChiaHungDuan struct TestSecondaryConfig : public TestPrimaryConfig { 62*2dc9ec47SChiaHungDuan struct Secondary { 63*2dc9ec47SChiaHungDuan template <typename Config> 64*2dc9ec47SChiaHungDuan using CacheT = scudo::MapAllocatorNoCache<Config>; 65*2dc9ec47SChiaHungDuan }; 66*2dc9ec47SChiaHungDuan }; 67*2dc9ec47SChiaHungDuan 68*2dc9ec47SChiaHungDuan struct TestSecondaryCacheConfigEnableOptionalFlag : public TestPrimaryConfig { 69*2dc9ec47SChiaHungDuan struct Secondary { 70*2dc9ec47SChiaHungDuan struct Cache { 71*2dc9ec47SChiaHungDuan static const scudo::u32 EntriesArraySize = 256U; getEntriesArraySizeTestSecondaryCacheConfigEnableOptionalFlag::Secondary::Cache72*2dc9ec47SChiaHungDuan static scudo::u32 getEntriesArraySize() { return EntriesArraySize; } 73*2dc9ec47SChiaHungDuan }; 74*2dc9ec47SChiaHungDuan template <typename T> using CacheT = scudo::MapAllocatorCache<T>; 75*2dc9ec47SChiaHungDuan }; 76*2dc9ec47SChiaHungDuan }; 77*2dc9ec47SChiaHungDuan TEST(ScudoAllocatorConfigTest,VerifyOptionalFlags)78*2dc9ec47SChiaHungDuanTEST(ScudoAllocatorConfigTest, VerifyOptionalFlags) { 79*2dc9ec47SChiaHungDuan // Test the top level allocator optional config. 80*2dc9ec47SChiaHungDuan // 81*2dc9ec47SChiaHungDuan // `MaySupportMemoryTagging` is default off. 82*2dc9ec47SChiaHungDuan EXPECT_FALSE(scudo::BaseConfig<TestBaseConfig>::getMaySupportMemoryTagging()); 83*2dc9ec47SChiaHungDuan EXPECT_EQ(scudo::BaseConfig< 84*2dc9ec47SChiaHungDuan TestBaseConfigEnableOptionalFlag>::getMaySupportMemoryTagging(), 85*2dc9ec47SChiaHungDuan TestBaseConfigEnableOptionalFlag::getMaySupportMemoryTagging()); 86*2dc9ec47SChiaHungDuan 87*2dc9ec47SChiaHungDuan // Test primary optional config. 88*2dc9ec47SChiaHungDuan // 89*2dc9ec47SChiaHungDuan // `EnableRandomeOffset` is default off. 90*2dc9ec47SChiaHungDuan EXPECT_FALSE( 91*2dc9ec47SChiaHungDuan scudo::PrimaryConfig<TestPrimaryConfig>::getEnableRandomOffset()); 92*2dc9ec47SChiaHungDuan EXPECT_EQ( 93*2dc9ec47SChiaHungDuan scudo::PrimaryConfig< 94*2dc9ec47SChiaHungDuan TestPrimaryConfigEnableOptionalFlag>::getEnableRandomOffset(), 95*2dc9ec47SChiaHungDuan TestPrimaryConfigEnableOptionalFlag::Primary::getEnableRandomOffset()); 96*2dc9ec47SChiaHungDuan 97*2dc9ec47SChiaHungDuan // `ConditionVariableT` is default off. 98*2dc9ec47SChiaHungDuan EXPECT_FALSE( 99*2dc9ec47SChiaHungDuan scudo::PrimaryConfig<TestPrimaryConfig>::hasConditionVariableT()); 100*2dc9ec47SChiaHungDuan EXPECT_TRUE(scudo::PrimaryConfig< 101*2dc9ec47SChiaHungDuan TestPrimaryConfigEnableOptionalType>::hasConditionVariableT()); 102*2dc9ec47SChiaHungDuan EXPECT_TRUE((std::is_same_v< 103*2dc9ec47SChiaHungDuan typename scudo::PrimaryConfig< 104*2dc9ec47SChiaHungDuan TestPrimaryConfigEnableOptionalType>::ConditionVariableT, 105*2dc9ec47SChiaHungDuan typename TestPrimaryConfigEnableOptionalType::Primary:: 106*2dc9ec47SChiaHungDuan ConditionVariableT>)); 107*2dc9ec47SChiaHungDuan 108*2dc9ec47SChiaHungDuan // Test secondary cache optional config. 109*2dc9ec47SChiaHungDuan using NoCacheConfig = 110*2dc9ec47SChiaHungDuan scudo::SecondaryConfig<TestSecondaryConfig>::CacheConfig; 111*2dc9ec47SChiaHungDuan // `EntriesArraySize` is default 0. 112*2dc9ec47SChiaHungDuan EXPECT_EQ(NoCacheConfig::getEntriesArraySize(), 0U); 113*2dc9ec47SChiaHungDuan 114*2dc9ec47SChiaHungDuan using CacheConfig = scudo::SecondaryConfig< 115*2dc9ec47SChiaHungDuan TestSecondaryCacheConfigEnableOptionalFlag>::CacheConfig; 116*2dc9ec47SChiaHungDuan EXPECT_EQ(CacheConfig::getEntriesArraySize(), 117*2dc9ec47SChiaHungDuan TestSecondaryCacheConfigEnableOptionalFlag::Secondary::Cache:: 118*2dc9ec47SChiaHungDuan getEntriesArraySize()); 119*2dc9ec47SChiaHungDuan } 120