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