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> 16extern "C" GWP_ASAN_WEAK void android_set_abort_message(const char *); 17#else // __BIONIC__ 18#include <stdio.h> 19#endif 20 21namespace gwp_asan { 22 23#ifdef __BIONIC__ 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__ 32void 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. 45static size_t alignBionic(size_t RealAllocationSize) { 46 if (RealAllocationSize % 8 == 0) 47 return RealAllocationSize; 48 return RealAllocationSize + 8 - (RealAllocationSize % 8); 49} 50 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__ 64static constexpr AlignmentStrategy PlatformDefaultAlignment = 65 AlignmentStrategy::BIONIC; 66#else // __BIONIC__ 67static constexpr AlignmentStrategy PlatformDefaultAlignment = 68 AlignmentStrategy::POWER_OF_TWO; 69#endif // __BIONIC__ 70 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