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