Path: blob/main/contrib/llvm-project/compiler-rt/lib/nsan/nsan_new_delete.cpp
213766 views
//===-- nsan_new_delete.cpp -----------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is a part of MemorySanitizer.9//10// Interceptors for operators new and delete.11//===----------------------------------------------------------------------===//1213#include "interception/interception.h"14#include "nsan.h"15#include "nsan_allocator.h"16#include "sanitizer_common/sanitizer_allocator.h"17#include "sanitizer_common/sanitizer_allocator_report.h"1819#include <stddef.h>2021using namespace __nsan;2223// Fake std::nothrow_t and std::align_val_t to avoid including <new>.24namespace std {25struct nothrow_t {};26enum class align_val_t : size_t {};27} // namespace std2829#define OPERATOR_NEW_BODY(nothrow) \30void *res = nsan_malloc(size); \31if (!nothrow && UNLIKELY(!res)) { \32BufferedStackTrace stack; \33GET_FATAL_STACK_TRACE_IF_EMPTY(&stack); \34ReportOutOfMemory(size, &stack); \35} \36return res37#define OPERATOR_NEW_BODY_ALIGN(nothrow) \38void *res = nsan_memalign((uptr)align, size); \39if (!nothrow && UNLIKELY(!res)) { \40BufferedStackTrace stack; \41GET_FATAL_STACK_TRACE_IF_EMPTY(&stack); \42ReportOutOfMemory(size, &stack); \43} \44return res;4546INTERCEPTOR_ATTRIBUTE47void *operator new(size_t size) { OPERATOR_NEW_BODY(/*nothrow=*/false); }48INTERCEPTOR_ATTRIBUTE49void *operator new[](size_t size) { OPERATOR_NEW_BODY(/*nothrow=*/false); }50INTERCEPTOR_ATTRIBUTE51void *operator new(size_t size, std::nothrow_t const &) {52OPERATOR_NEW_BODY(/*nothrow=*/true);53}54INTERCEPTOR_ATTRIBUTE55void *operator new[](size_t size, std::nothrow_t const &) {56OPERATOR_NEW_BODY(/*nothrow=*/true);57}58INTERCEPTOR_ATTRIBUTE59void *operator new(size_t size, std::align_val_t align) {60OPERATOR_NEW_BODY_ALIGN(/*nothrow=*/false);61}62INTERCEPTOR_ATTRIBUTE63void *operator new[](size_t size, std::align_val_t align) {64OPERATOR_NEW_BODY_ALIGN(/*nothrow=*/false);65}66INTERCEPTOR_ATTRIBUTE67void *operator new(size_t size, std::align_val_t align,68std::nothrow_t const &) {69OPERATOR_NEW_BODY_ALIGN(/*nothrow=*/true);70}71INTERCEPTOR_ATTRIBUTE72void *operator new[](size_t size, std::align_val_t align,73std::nothrow_t const &) {74OPERATOR_NEW_BODY_ALIGN(/*nothrow=*/true);75}7677#define OPERATOR_DELETE_BODY \78if (ptr) \79NsanDeallocate(ptr)8081INTERCEPTOR_ATTRIBUTE82void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }83INTERCEPTOR_ATTRIBUTE84void operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }85INTERCEPTOR_ATTRIBUTE86void operator delete(void *ptr, std::nothrow_t const &) {87OPERATOR_DELETE_BODY;88}89INTERCEPTOR_ATTRIBUTE90void operator delete[](void *ptr, std::nothrow_t const &) {91OPERATOR_DELETE_BODY;92}93INTERCEPTOR_ATTRIBUTE94void operator delete(void *ptr, size_t size) NOEXCEPT { OPERATOR_DELETE_BODY; }95INTERCEPTOR_ATTRIBUTE96void operator delete[](void *ptr, size_t size) NOEXCEPT {97OPERATOR_DELETE_BODY;98}99INTERCEPTOR_ATTRIBUTE100void operator delete(void *ptr, std::align_val_t align) NOEXCEPT {101OPERATOR_DELETE_BODY;102}103INTERCEPTOR_ATTRIBUTE104void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT {105OPERATOR_DELETE_BODY;106}107INTERCEPTOR_ATTRIBUTE108void operator delete(void *ptr, std::align_val_t align,109std::nothrow_t const &) {110OPERATOR_DELETE_BODY;111}112INTERCEPTOR_ATTRIBUTE113void operator delete[](void *ptr, std::align_val_t align,114std::nothrow_t const &) {115OPERATOR_DELETE_BODY;116}117INTERCEPTOR_ATTRIBUTE118void operator delete(void *ptr, size_t size, std::align_val_t align) NOEXCEPT {119OPERATOR_DELETE_BODY;120}121INTERCEPTOR_ATTRIBUTE122void operator delete[](void *ptr, size_t size,123std::align_val_t align) NOEXCEPT {124OPERATOR_DELETE_BODY;125}126127128