Home | History | Annotate | Line # | Download | only in msan
      1 //===-- msan_new_delete.cc ------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is a part of MemorySanitizer.
     11 //
     12 // Interceptors for operators new and delete.
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "msan.h"
     16 #include "interception/interception.h"
     17 #include "sanitizer_common/sanitizer_allocator.h"
     18 #include "sanitizer_common/sanitizer_allocator_report.h"
     19 
     20 #if MSAN_REPLACE_OPERATORS_NEW_AND_DELETE
     21 
     22 #include <stddef.h>
     23 
     24 using namespace __msan;  // NOLINT
     25 
     26 // Fake std::nothrow_t and std::align_val_t to avoid including <new>.
     27 namespace std {
     28   struct nothrow_t {};
     29   enum class align_val_t: size_t {};
     30 }  // namespace std
     31 
     32 
     33 // TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
     34 #define OPERATOR_NEW_BODY(nothrow) \
     35   GET_MALLOC_STACK_TRACE; \
     36   void *res = msan_malloc(size, &stack);\
     37   if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
     38   return res
     39 #define OPERATOR_NEW_BODY_ALIGN(nothrow) \
     40   GET_MALLOC_STACK_TRACE;\
     41   void *res = msan_memalign((uptr)align, size, &stack);\
     42   if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
     43   return res;
     44 
     45 INTERCEPTOR_ATTRIBUTE
     46 void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
     47 INTERCEPTOR_ATTRIBUTE
     48 void *operator new[](size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
     49 INTERCEPTOR_ATTRIBUTE
     50 void *operator new(size_t size, std::nothrow_t const&) {
     51   OPERATOR_NEW_BODY(true /*nothrow*/);
     52 }
     53 INTERCEPTOR_ATTRIBUTE
     54 void *operator new[](size_t size, std::nothrow_t const&) {
     55   OPERATOR_NEW_BODY(true /*nothrow*/);
     56 }
     57 INTERCEPTOR_ATTRIBUTE
     58 void *operator new(size_t size, std::align_val_t align)
     59 { OPERATOR_NEW_BODY_ALIGN(false /*nothrow*/); }
     60 INTERCEPTOR_ATTRIBUTE
     61 void *operator new[](size_t size, std::align_val_t align)
     62 { OPERATOR_NEW_BODY_ALIGN(false /*nothrow*/); }
     63 INTERCEPTOR_ATTRIBUTE
     64 void *operator new(size_t size, std::align_val_t align, std::nothrow_t const&)
     65 { OPERATOR_NEW_BODY_ALIGN(true /*nothrow*/); }
     66 INTERCEPTOR_ATTRIBUTE
     67 void *operator new[](size_t size, std::align_val_t align, std::nothrow_t const&)
     68 { OPERATOR_NEW_BODY_ALIGN(true /*nothrow*/); }
     69 
     70 #define OPERATOR_DELETE_BODY \
     71   GET_MALLOC_STACK_TRACE; \
     72   if (ptr) MsanDeallocate(&stack, ptr)
     73 
     74 INTERCEPTOR_ATTRIBUTE
     75 void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
     76 INTERCEPTOR_ATTRIBUTE
     77 void operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
     78 INTERCEPTOR_ATTRIBUTE
     79 void operator delete(void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; }
     80 INTERCEPTOR_ATTRIBUTE
     81 void operator delete[](void *ptr, std::nothrow_t const&) {
     82   OPERATOR_DELETE_BODY;
     83 }
     84 INTERCEPTOR_ATTRIBUTE
     85 void operator delete(void *ptr, size_t size) NOEXCEPT { OPERATOR_DELETE_BODY; }
     86 INTERCEPTOR_ATTRIBUTE
     87 void operator delete[](void *ptr, size_t size) NOEXCEPT
     88 { OPERATOR_DELETE_BODY; }
     89 INTERCEPTOR_ATTRIBUTE
     90 void operator delete(void *ptr, std::align_val_t align) NOEXCEPT
     91 { OPERATOR_DELETE_BODY; }
     92 INTERCEPTOR_ATTRIBUTE
     93 void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT
     94 { OPERATOR_DELETE_BODY; }
     95 INTERCEPTOR_ATTRIBUTE
     96 void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&)
     97 { OPERATOR_DELETE_BODY; }
     98 INTERCEPTOR_ATTRIBUTE
     99 void operator delete[](void *ptr, std::align_val_t align, std::nothrow_t const&)
    100 { OPERATOR_DELETE_BODY; }
    101 INTERCEPTOR_ATTRIBUTE
    102 void operator delete(void *ptr, size_t size, std::align_val_t align) NOEXCEPT
    103 { OPERATOR_DELETE_BODY; }
    104 INTERCEPTOR_ATTRIBUTE
    105 void operator delete[](void *ptr, size_t size, std::align_val_t align) NOEXCEPT
    106 { OPERATOR_DELETE_BODY; }
    107 
    108 
    109 #endif // MSAN_REPLACE_OPERATORS_NEW_AND_DELETE
    110