Path: blob/main/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_new_delete.cpp
35233 views
//===-- dfsan_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 DataflowSanitizer.9//10// Interceptors for operators new and delete.11//===----------------------------------------------------------------------===//1213#include <stddef.h>1415#include "dfsan.h"16#include "interception/interception.h"17#include "sanitizer_common/sanitizer_allocator.h"18#include "sanitizer_common/sanitizer_allocator_report.h"1920using namespace __dfsan;2122// Fake std::nothrow_t and std::align_val_t to avoid including <new>.23namespace std {24struct nothrow_t {};25enum class align_val_t : size_t {};26} // namespace std2728// TODO(alekseys): throw std::bad_alloc instead of dying on OOM.29#define OPERATOR_NEW_BODY(nothrow) \30void *res = dfsan_malloc(size); \31if (!nothrow && UNLIKELY(!res)) { \32BufferedStackTrace stack; \33ReportOutOfMemory(size, &stack); \34} \35return res36#define OPERATOR_NEW_BODY_ALIGN(nothrow) \37void *res = dfsan_memalign((uptr)align, size); \38if (!nothrow && UNLIKELY(!res)) { \39BufferedStackTrace stack; \40ReportOutOfMemory(size, &stack); \41} \42return res;4344INTERCEPTOR_ATTRIBUTE45void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }46INTERCEPTOR_ATTRIBUTE47void *operator new[](size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }48INTERCEPTOR_ATTRIBUTE49void *operator new(size_t size, std::nothrow_t const &) {50OPERATOR_NEW_BODY(true /*nothrow*/);51}52INTERCEPTOR_ATTRIBUTE53void *operator new[](size_t size, std::nothrow_t const &) {54OPERATOR_NEW_BODY(true /*nothrow*/);55}56INTERCEPTOR_ATTRIBUTE57void *operator new(size_t size, std::align_val_t align) {58OPERATOR_NEW_BODY_ALIGN(false /*nothrow*/);59}60INTERCEPTOR_ATTRIBUTE61void *operator new[](size_t size, std::align_val_t align) {62OPERATOR_NEW_BODY_ALIGN(false /*nothrow*/);63}64INTERCEPTOR_ATTRIBUTE65void *operator new(size_t size, std::align_val_t align,66std::nothrow_t const &) {67OPERATOR_NEW_BODY_ALIGN(true /*nothrow*/);68}69INTERCEPTOR_ATTRIBUTE70void *operator new[](size_t size, std::align_val_t align,71std::nothrow_t const &) {72OPERATOR_NEW_BODY_ALIGN(true /*nothrow*/);73}7475#define OPERATOR_DELETE_BODY \76if (ptr) \77dfsan_deallocate(ptr)7879INTERCEPTOR_ATTRIBUTE80void operator delete(void *ptr)NOEXCEPT { OPERATOR_DELETE_BODY; }81INTERCEPTOR_ATTRIBUTE82void operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }83INTERCEPTOR_ATTRIBUTE84void operator delete(void *ptr, std::nothrow_t const &) {85OPERATOR_DELETE_BODY;86}87INTERCEPTOR_ATTRIBUTE88void operator delete[](void *ptr, std::nothrow_t const &) {89OPERATOR_DELETE_BODY;90}91INTERCEPTOR_ATTRIBUTE92void operator delete(void *ptr, size_t size)NOEXCEPT { OPERATOR_DELETE_BODY; }93INTERCEPTOR_ATTRIBUTE94void operator delete[](void *ptr, size_t size) NOEXCEPT {95OPERATOR_DELETE_BODY;96}97INTERCEPTOR_ATTRIBUTE98void operator delete(void *ptr, std::align_val_t align)NOEXCEPT {99OPERATOR_DELETE_BODY;100}101INTERCEPTOR_ATTRIBUTE102void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT {103OPERATOR_DELETE_BODY;104}105INTERCEPTOR_ATTRIBUTE106void operator delete(void *ptr, std::align_val_t align,107std::nothrow_t const &) {108OPERATOR_DELETE_BODY;109}110INTERCEPTOR_ATTRIBUTE111void operator delete[](void *ptr, std::align_val_t align,112std::nothrow_t const &) {113OPERATOR_DELETE_BODY;114}115INTERCEPTOR_ATTRIBUTE116void operator delete(void *ptr, size_t size, std::align_val_t align)NOEXCEPT {117OPERATOR_DELETE_BODY;118}119INTERCEPTOR_ATTRIBUTE120void operator delete[](void *ptr, size_t size,121std::align_val_t align) NOEXCEPT {122OPERATOR_DELETE_BODY;123}124125126