summaryrefslogtreecommitdiff
path: root/compiler-rt/lib/gwp_asan/platform_specific/utilities_posix.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /compiler-rt/lib/gwp_asan/platform_specific/utilities_posix.cpp
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
Notes
Diffstat (limited to 'compiler-rt/lib/gwp_asan/platform_specific/utilities_posix.cpp')
-rw-r--r--compiler-rt/lib/gwp_asan/platform_specific/utilities_posix.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/compiler-rt/lib/gwp_asan/platform_specific/utilities_posix.cpp b/compiler-rt/lib/gwp_asan/platform_specific/utilities_posix.cpp
new file mode 100644
index 000000000000..0e6059896702
--- /dev/null
+++ b/compiler-rt/lib/gwp_asan/platform_specific/utilities_posix.cpp
@@ -0,0 +1,90 @@
+//===-- utilities_posix.cpp -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "gwp_asan/definitions.h"
+#include "gwp_asan/utilities.h"
+
+#include <assert.h>
+
+#ifdef __BIONIC__
+#include <stdlib.h>
+extern "C" GWP_ASAN_WEAK void android_set_abort_message(const char *);
+#else // __BIONIC__
+#include <stdio.h>
+#endif
+
+namespace gwp_asan {
+
+#ifdef __BIONIC__
+void Check(bool Condition, const char *Message) {
+ if (Condition)
+ return;
+ if (&android_set_abort_message != nullptr)
+ android_set_abort_message(Message);
+ abort();
+}
+#else // __BIONIC__
+void Check(bool Condition, const char *Message) {
+ if (Condition)
+ return;
+ fprintf(stderr, "%s", Message);
+ __builtin_trap();
+}
+#endif // __BIONIC__
+
+// See `bionic/tests/malloc_test.cpp` in the Android source for documentation
+// regarding their alignment guarantees. We always round up to the closest
+// 8-byte window. As GWP-ASan's malloc(X) can always get exactly an X-sized
+// allocation, an allocation that rounds up to 16-bytes will always be given a
+// 16-byte aligned allocation.
+static size_t alignBionic(size_t RealAllocationSize) {
+ if (RealAllocationSize % 8 == 0)
+ return RealAllocationSize;
+ return RealAllocationSize + 8 - (RealAllocationSize % 8);
+}
+
+static size_t alignPowerOfTwo(size_t RealAllocationSize) {
+ if (RealAllocationSize <= 2)
+ return RealAllocationSize;
+ if (RealAllocationSize <= 4)
+ return 4;
+ if (RealAllocationSize <= 8)
+ return 8;
+ if (RealAllocationSize % 16 == 0)
+ return RealAllocationSize;
+ return RealAllocationSize + 16 - (RealAllocationSize % 16);
+}
+
+#ifdef __BIONIC__
+static constexpr AlignmentStrategy PlatformDefaultAlignment =
+ AlignmentStrategy::BIONIC;
+#else // __BIONIC__
+static constexpr AlignmentStrategy PlatformDefaultAlignment =
+ AlignmentStrategy::POWER_OF_TWO;
+#endif // __BIONIC__
+
+size_t rightAlignedAllocationSize(size_t RealAllocationSize,
+ AlignmentStrategy Align) {
+ assert(RealAllocationSize > 0);
+ if (Align == AlignmentStrategy::DEFAULT)
+ Align = PlatformDefaultAlignment;
+
+ switch (Align) {
+ case AlignmentStrategy::BIONIC:
+ return alignBionic(RealAllocationSize);
+ case AlignmentStrategy::POWER_OF_TWO:
+ return alignPowerOfTwo(RealAllocationSize);
+ case AlignmentStrategy::PERFECT:
+ return RealAllocationSize;
+ case AlignmentStrategy::DEFAULT:
+ __builtin_unreachable();
+ }
+ __builtin_unreachable();
+}
+
+} // namespace gwp_asan