1 //===-- utilities_posix.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/definitions.h" 10 #include "gwp_asan/utilities.h" 11 12 #include <assert.h> 13 14 #ifdef __BIONIC__ 15 #include <stdlib.h> 16 extern "C" GWP_ASAN_WEAK void android_set_abort_message(const char *); 17 #else // __BIONIC__ 18 #include <stdio.h> 19 #endif 20 21 namespace gwp_asan { 22 23 #ifdef __BIONIC__ Check(bool Condition,const char * Message)24void Check(bool Condition, const char *Message) { 25 if (Condition) 26 return; 27 if (&android_set_abort_message != nullptr) 28 android_set_abort_message(Message); 29 abort(); 30 } 31 #else // __BIONIC__ 32 void Check(bool Condition, const char *Message) { 33 if (Condition) 34 return; 35 fprintf(stderr, "%s", Message); 36 __builtin_trap(); 37 } 38 #endif // __BIONIC__ 39 40 // See `bionic/tests/malloc_test.cpp` in the Android source for documentation 41 // regarding their alignment guarantees. We always round up to the closest 42 // 8-byte window. As GWP-ASan's malloc(X) can always get exactly an X-sized 43 // allocation, an allocation that rounds up to 16-bytes will always be given a 44 // 16-byte aligned allocation. alignBionic(size_t RealAllocationSize)45static size_t alignBionic(size_t RealAllocationSize) { 46 if (RealAllocationSize % 8 == 0) 47 return RealAllocationSize; 48 return RealAllocationSize + 8 - (RealAllocationSize % 8); 49 } 50 alignPowerOfTwo(size_t RealAllocationSize)51static size_t alignPowerOfTwo(size_t RealAllocationSize) { 52 if (RealAllocationSize <= 2) 53 return RealAllocationSize; 54 if (RealAllocationSize <= 4) 55 return 4; 56 if (RealAllocationSize <= 8) 57 return 8; 58 if (RealAllocationSize % 16 == 0) 59 return RealAllocationSize; 60 return RealAllocationSize + 16 - (RealAllocationSize % 16); 61 } 62 63 #ifdef __BIONIC__ 64 static constexpr AlignmentStrategy PlatformDefaultAlignment = 65 AlignmentStrategy::BIONIC; 66 #else // __BIONIC__ 67 static constexpr AlignmentStrategy PlatformDefaultAlignment = 68 AlignmentStrategy::POWER_OF_TWO; 69 #endif // __BIONIC__ 70 rightAlignedAllocationSize(size_t RealAllocationSize,AlignmentStrategy Align)71size_t rightAlignedAllocationSize(size_t RealAllocationSize, 72 AlignmentStrategy Align) { 73 assert(RealAllocationSize > 0); 74 if (Align == AlignmentStrategy::DEFAULT) 75 Align = PlatformDefaultAlignment; 76 77 switch (Align) { 78 case AlignmentStrategy::BIONIC: 79 return alignBionic(RealAllocationSize); 80 case AlignmentStrategy::POWER_OF_TWO: 81 return alignPowerOfTwo(RealAllocationSize); 82 case AlignmentStrategy::PERFECT: 83 return RealAllocationSize; 84 case AlignmentStrategy::DEFAULT: 85 __builtin_unreachable(); 86 } 87 __builtin_unreachable(); 88 } 89 90 } // namespace gwp_asan 91