1 //===-- utilities.cpp -------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "gwp_asan/utilities.h" 10 11 #include <assert.h> 12 13 namespace gwp_asan { 14 // See `bionic/tests/malloc_test.cpp` in the Android source for documentation 15 // regarding their alignment guarantees. We always round up to the closest 16 // 8-byte window. As GWP-ASan's malloc(X) can always get exactly an X-sized 17 // allocation, an allocation that rounds up to 16-bytes will always be given a 18 // 16-byte aligned allocation. alignBionic(size_t RealAllocationSize)19static size_t alignBionic(size_t RealAllocationSize) { 20 if (RealAllocationSize % 8 == 0) 21 return RealAllocationSize; 22 return RealAllocationSize + 8 - (RealAllocationSize % 8); 23 } 24 alignPowerOfTwo(size_t RealAllocationSize)25static size_t alignPowerOfTwo(size_t RealAllocationSize) { 26 if (RealAllocationSize <= 2) 27 return RealAllocationSize; 28 if (RealAllocationSize <= 4) 29 return 4; 30 if (RealAllocationSize <= 8) 31 return 8; 32 if (RealAllocationSize % 16 == 0) 33 return RealAllocationSize; 34 return RealAllocationSize + 16 - (RealAllocationSize % 16); 35 } 36 37 #ifdef __BIONIC__ 38 static constexpr AlignmentStrategy PlatformDefaultAlignment = 39 AlignmentStrategy::BIONIC; 40 #else // __BIONIC__ 41 static constexpr AlignmentStrategy PlatformDefaultAlignment = 42 AlignmentStrategy::POWER_OF_TWO; 43 #endif // __BIONIC__ 44 rightAlignedAllocationSize(size_t RealAllocationSize,AlignmentStrategy Align)45size_t rightAlignedAllocationSize(size_t RealAllocationSize, 46 AlignmentStrategy Align) { 47 assert(RealAllocationSize > 0); 48 if (Align == AlignmentStrategy::DEFAULT) 49 Align = PlatformDefaultAlignment; 50 51 switch (Align) { 52 case AlignmentStrategy::BIONIC: 53 return alignBionic(RealAllocationSize); 54 case AlignmentStrategy::POWER_OF_TWO: 55 return alignPowerOfTwo(RealAllocationSize); 56 case AlignmentStrategy::PERFECT: 57 return RealAllocationSize; 58 case AlignmentStrategy::DEFAULT: 59 __builtin_unreachable(); 60 } 61 __builtin_unreachable(); 62 } 63 } // namespace gwp_asan 64