summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc')
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc57
1 files changed, 19 insertions, 38 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc
index 0fdaef17f87..6bfd5e5eea5 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc
@@ -140,12 +140,19 @@ static void RawInternalFree(void *ptr, InternalAllocatorCache *cache) {
const u64 kBlockMagic = 0x6A6CB03ABCEBC041ull;
+static void NORETURN ReportInternalAllocatorOutOfMemory(uptr requested_size) {
+ SetAllocatorOutOfMemory();
+ Report("FATAL: %s: internal allocator is out of memory trying to allocate "
+ "0x%zx bytes\n", SanitizerToolName, requested_size);
+ Die();
+}
+
void *InternalAlloc(uptr size, InternalAllocatorCache *cache, uptr alignment) {
if (size + sizeof(u64) < size)
return nullptr;
void *p = RawInternalAlloc(size + sizeof(u64), cache, alignment);
if (UNLIKELY(!p))
- return DieOnFailure::OnOOM();
+ ReportInternalAllocatorOutOfMemory(size + sizeof(u64));
((u64*)p)[0] = kBlockMagic;
return (char*)p + sizeof(u64);
}
@@ -160,13 +167,17 @@ void *InternalRealloc(void *addr, uptr size, InternalAllocatorCache *cache) {
CHECK_EQ(kBlockMagic, ((u64*)addr)[0]);
void *p = RawInternalRealloc(addr, size, cache);
if (UNLIKELY(!p))
- return DieOnFailure::OnOOM();
+ ReportInternalAllocatorOutOfMemory(size);
return (char*)p + sizeof(u64);
}
void *InternalCalloc(uptr count, uptr size, InternalAllocatorCache *cache) {
- if (UNLIKELY(CheckForCallocOverflow(count, size)))
- return DieOnFailure::OnBadRequest();
+ if (UNLIKELY(CheckForCallocOverflow(count, size))) {
+ Report("FATAL: %s: calloc parameters overflow: count * size (%zd * %zd) "
+ "cannot be represented in type size_t\n", SanitizerToolName, count,
+ size);
+ Die();
+ }
void *p = InternalAlloc(count * size, cache);
if (LIKELY(p))
internal_memset(p, 0, count * size);
@@ -215,6 +226,8 @@ void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback) {
low_level_alloc_callback = callback;
}
+// Allocator's OOM and other errors handling support.
+
static atomic_uint8_t allocator_out_of_memory = {0};
static atomic_uint8_t allocator_may_return_null = {0};
@@ -226,15 +239,6 @@ void SetAllocatorOutOfMemory() {
atomic_store_relaxed(&allocator_out_of_memory, 1);
}
-// Prints error message and kills the program.
-void NORETURN ReportAllocatorCannotReturnNull() {
- Report("%s's allocator is terminating the process instead of returning 0\n",
- SanitizerToolName);
- Report("If you don't like this behavior set allocator_may_return_null=1\n");
- CHECK(0);
- Die();
-}
-
bool AllocatorMayReturnNull() {
return atomic_load(&allocator_may_return_null, memory_order_relaxed);
}
@@ -244,32 +248,9 @@ void SetAllocatorMayReturnNull(bool may_return_null) {
memory_order_relaxed);
}
-void *ReturnNullOrDieOnFailure::OnBadRequest() {
- if (AllocatorMayReturnNull())
- return nullptr;
- ReportAllocatorCannotReturnNull();
-}
-
-void *ReturnNullOrDieOnFailure::OnOOM() {
- atomic_store_relaxed(&allocator_out_of_memory, 1);
- if (AllocatorMayReturnNull())
- return nullptr;
- ReportAllocatorCannotReturnNull();
-}
-
-void NORETURN *DieOnFailure::OnBadRequest() {
- ReportAllocatorCannotReturnNull();
-}
-
-void NORETURN *DieOnFailure::OnOOM() {
- atomic_store_relaxed(&allocator_out_of_memory, 1);
- ReportAllocatorCannotReturnNull();
-}
-
-// Prints hint message.
-void PrintHintAllocatorCannotReturnNull(const char *options_name) {
+void PrintHintAllocatorCannotReturnNull() {
Report("HINT: if you don't care about these errors you may set "
- "%s=allocator_may_return_null=1\n", options_name);
+ "allocator_may_return_null=1\n");
}
} // namespace __sanitizer
OpenPOWER on IntegriCloud