1//===-- sanitizer_allocator_report.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/// \file
10/// Shared allocator error reporting for ThreadSanitizer, MemorySanitizer, etc.
11///
12//===----------------------------------------------------------------------===//
13
14#include "sanitizer_allocator.h"
15#include "sanitizer_allocator_report.h"
16#include "sanitizer_common.h"
17#include "sanitizer_report_decorator.h"
18
19namespace __sanitizer {
20
21class ScopedAllocatorErrorReport {
22 public:
23  ScopedAllocatorErrorReport(const char *error_summary_,
24                             const StackTrace *stack_)
25      : error_summary(error_summary_),
26        stack(stack_) {
27    Printf("%s", d.Error());
28  }
29  ~ScopedAllocatorErrorReport() {
30    Printf("%s", d.Default());
31    stack->Print();
32    PrintHintAllocatorCannotReturnNull();
33    ReportErrorSummary(error_summary, stack);
34  }
35
36 private:
37  ScopedErrorReportLock lock;
38  const char *error_summary;
39  const StackTrace* const stack;
40  const SanitizerCommonDecorator d;
41};
42
43void NORETURN ReportCallocOverflow(uptr count, uptr size,
44                                   const StackTrace *stack) {
45  {
46    ScopedAllocatorErrorReport report("calloc-overflow", stack);
47    Report("ERROR: %s: calloc parameters overflow: count * size (%zd * %zd) "
48           "cannot be represented in type size_t\n", SanitizerToolName, count,
49           size);
50  }
51  Die();
52}
53
54void NORETURN ReportReallocArrayOverflow(uptr count, uptr size,
55                                         const StackTrace *stack) {
56  {
57    ScopedAllocatorErrorReport report("reallocarray-overflow", stack);
58    Report(
59        "ERROR: %s: reallocarray parameters overflow: count * size (%zd * %zd) "
60        "cannot be represented in type size_t\n",
61        SanitizerToolName, count, size);
62  }
63  Die();
64}
65
66void NORETURN ReportPvallocOverflow(uptr size, const StackTrace *stack) {
67  {
68    ScopedAllocatorErrorReport report("pvalloc-overflow", stack);
69    Report("ERROR: %s: pvalloc parameters overflow: size 0x%zx rounded up to "
70           "system page size 0x%zx cannot be represented in type size_t\n",
71           SanitizerToolName, size, GetPageSizeCached());
72  }
73  Die();
74}
75
76void NORETURN ReportInvalidAllocationAlignment(uptr alignment,
77                                               const StackTrace *stack) {
78  {
79    ScopedAllocatorErrorReport report("invalid-allocation-alignment", stack);
80    Report("ERROR: %s: invalid allocation alignment: %zd, alignment must be a "
81           "power of two\n", SanitizerToolName, alignment);
82  }
83  Die();
84}
85
86void NORETURN ReportInvalidAlignedAllocAlignment(uptr size, uptr alignment,
87                                                 const StackTrace *stack) {
88  {
89    ScopedAllocatorErrorReport report("invalid-aligned-alloc-alignment", stack);
90#if SANITIZER_POSIX
91    Report("ERROR: %s: invalid alignment requested in "
92           "aligned_alloc: %zd, alignment must be a power of two and the "
93           "requested size 0x%zx must be a multiple of alignment\n",
94           SanitizerToolName, alignment, size);
95#else
96    Report("ERROR: %s: invalid alignment requested in aligned_alloc: %zd, "
97           "the requested size 0x%zx must be a multiple of alignment\n",
98           SanitizerToolName, alignment, size);
99#endif
100  }
101  Die();
102}
103
104void NORETURN ReportInvalidPosixMemalignAlignment(uptr alignment,
105                                                  const StackTrace *stack) {
106  {
107    ScopedAllocatorErrorReport report("invalid-posix-memalign-alignment",
108                                      stack);
109    Report(
110        "ERROR: %s: invalid alignment requested in "
111        "posix_memalign: %zd, alignment must be a power of two and a "
112        "multiple of sizeof(void*) == %zd\n",
113        SanitizerToolName, alignment, sizeof(void *));
114  }
115  Die();
116}
117
118void NORETURN ReportAllocationSizeTooBig(uptr user_size, uptr max_size,
119                                         const StackTrace *stack) {
120  {
121    ScopedAllocatorErrorReport report("allocation-size-too-big", stack);
122    Report("ERROR: %s: requested allocation size 0x%zx exceeds maximum "
123           "supported size of 0x%zx\n", SanitizerToolName, user_size, max_size);
124  }
125  Die();
126}
127
128void NORETURN ReportOutOfMemory(uptr requested_size, const StackTrace *stack) {
129  {
130    ScopedAllocatorErrorReport report("out-of-memory", stack);
131    Report("ERROR: %s: allocator is out of memory trying to allocate 0x%zx "
132           "bytes\n", SanitizerToolName, requested_size);
133  }
134  Die();
135}
136
137}  // namespace __sanitizer
138