154263Sshin//===-- memprof_interceptors.cpp -----------------------------------------===// 254263Sshin// 354263Sshin// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 454263Sshin// See https://llvm.org/LICENSE.txt for license information. 554263Sshin// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 654263Sshin// 754263Sshin//===----------------------------------------------------------------------===// 854263Sshin// 954263Sshin// This file is a part of MemProfiler, a memory profiler. 1054263Sshin// 1154263Sshin// Interceptors for operators new and delete. 1254263Sshin//===----------------------------------------------------------------------===// 1354263Sshin 1454263Sshin#include "memprof_allocator.h" 1554263Sshin#include "memprof_internal.h" 1654263Sshin#include "memprof_stack.h" 1754263Sshin#include "sanitizer_common/sanitizer_allocator_report.h" 1854263Sshin 1954263Sshin#include "interception/interception.h" 2054263Sshin 2154263Sshin#include <stddef.h> 2254263Sshin 2354263Sshin#define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE 2454263Sshin 2554263Sshinusing namespace __memprof; 2654263Sshin 2754263Sshin// Fake std::nothrow_t and std::align_val_t to avoid including <new>. 2854263Sshinnamespace std { 2954263Sshinstruct nothrow_t {}; 3054263Sshinenum class align_val_t : size_t {}; 3154263Sshin} // namespace std 3254263Sshin 3354263Sshin#define OPERATOR_NEW_BODY(type, nothrow) \ 3454263Sshin GET_STACK_TRACE_MALLOC; \ 3554263Sshin void *res = memprof_memalign(0, size, &stack, type); \ 3654263Sshin if (!nothrow && UNLIKELY(!res)) \ 3754263Sshin ReportOutOfMemory(size, &stack); \ 3854263Sshin return res; 3954263Sshin#define OPERATOR_NEW_BODY_ALIGN(type, nothrow) \ 4054263Sshin GET_STACK_TRACE_MALLOC; \ 4154263Sshin void *res = memprof_memalign((uptr)align, size, &stack, type); \ 4254263Sshin if (!nothrow && UNLIKELY(!res)) \ 4354263Sshin ReportOutOfMemory(size, &stack); \ 4454263Sshin return res; 4554263Sshin 4654263SshinCXX_OPERATOR_ATTRIBUTE 4754263Sshinvoid *operator new(size_t size) { 4854263Sshin OPERATOR_NEW_BODY(FROM_NEW, false /*nothrow*/); 4954263Sshin} 5054263SshinCXX_OPERATOR_ATTRIBUTE 5154263Sshinvoid *operator new[](size_t size) { 5254263Sshin OPERATOR_NEW_BODY(FROM_NEW_BR, false /*nothrow*/); 5354263Sshin} 5454263SshinCXX_OPERATOR_ATTRIBUTE 5554263Sshinvoid *operator new(size_t size, std::nothrow_t const &) { 5654263Sshin OPERATOR_NEW_BODY(FROM_NEW, true /*nothrow*/); 5754263Sshin} 5855009SshinCXX_OPERATOR_ATTRIBUTE 5955009Sshinvoid *operator new[](size_t size, std::nothrow_t const &) { 6054263Sshin OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/); 6154263Sshin} 6254263SshinCXX_OPERATOR_ATTRIBUTE 6354263Sshinvoid *operator new(size_t size, std::align_val_t align) { 6454263Sshin OPERATOR_NEW_BODY_ALIGN(FROM_NEW, false /*nothrow*/); 6554263Sshin} 6654263SshinCXX_OPERATOR_ATTRIBUTE 6754263Sshinvoid *operator new[](size_t size, std::align_val_t align) { 6854263Sshin OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, false /*nothrow*/); 6954263Sshin} 7054263SshinCXX_OPERATOR_ATTRIBUTE 7154263Sshinvoid *operator new(size_t size, std::align_val_t align, 7254263Sshin std::nothrow_t const &) { 7354263Sshin OPERATOR_NEW_BODY_ALIGN(FROM_NEW, true /*nothrow*/); 7454263Sshin} 7554263SshinCXX_OPERATOR_ATTRIBUTE 7654263Sshinvoid *operator new[](size_t size, std::align_val_t align, 7754263Sshin std::nothrow_t const &) { 7855009Sshin OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, true /*nothrow*/); 7954263Sshin} 8054263Sshin 8154263Sshin#define OPERATOR_DELETE_BODY(type) \ 8254263Sshin GET_STACK_TRACE_FREE; \ 8354263Sshin memprof_delete(ptr, 0, 0, &stack, type); 8454263Sshin 8554263Sshin#define OPERATOR_DELETE_BODY_SIZE(type) \ 8654263Sshin GET_STACK_TRACE_FREE; \ 8754263Sshin memprof_delete(ptr, size, 0, &stack, type); 8854263Sshin 8954263Sshin#define OPERATOR_DELETE_BODY_ALIGN(type) \ 9054263Sshin GET_STACK_TRACE_FREE; \ 9154263Sshin memprof_delete(ptr, 0, static_cast<uptr>(align), &stack, type); 9254263Sshin 9354263Sshin#define OPERATOR_DELETE_BODY_SIZE_ALIGN(type) \ 9454263Sshin GET_STACK_TRACE_FREE; \ 9554263Sshin memprof_delete(ptr, size, static_cast<uptr>(align), &stack, type); 9654263Sshin 9754263SshinCXX_OPERATOR_ATTRIBUTE 9854263Sshinvoid operator delete(void *ptr)NOEXCEPT { OPERATOR_DELETE_BODY(FROM_NEW); } 9954263SshinCXX_OPERATOR_ATTRIBUTE 10055009Sshinvoid operator delete[](void *ptr) NOEXCEPT { 10154263Sshin OPERATOR_DELETE_BODY(FROM_NEW_BR); 10254263Sshin} 10354263SshinCXX_OPERATOR_ATTRIBUTE 10454263Sshinvoid operator delete(void *ptr, std::nothrow_t const &) { 10554263Sshin OPERATOR_DELETE_BODY(FROM_NEW); 10654263Sshin} 10754263SshinCXX_OPERATOR_ATTRIBUTE 10854263Sshinvoid operator delete[](void *ptr, std::nothrow_t const &) { 10954263Sshin OPERATOR_DELETE_BODY(FROM_NEW_BR); 11054263Sshin} 11154263SshinCXX_OPERATOR_ATTRIBUTE 11254263Sshinvoid operator delete(void *ptr, size_t size)NOEXCEPT { 11354263Sshin OPERATOR_DELETE_BODY_SIZE(FROM_NEW); 11455009Sshin} 11554263SshinCXX_OPERATOR_ATTRIBUTE 11654263Sshinvoid operator delete[](void *ptr, size_t size) NOEXCEPT { 11754263Sshin OPERATOR_DELETE_BODY_SIZE(FROM_NEW_BR); 11854263Sshin} 11954263SshinCXX_OPERATOR_ATTRIBUTE 12054263Sshinvoid operator delete(void *ptr, std::align_val_t align)NOEXCEPT { 12154263Sshin OPERATOR_DELETE_BODY_ALIGN(FROM_NEW); 12254263Sshin} 12354263SshinCXX_OPERATOR_ATTRIBUTE 12454263Sshinvoid operator delete[](void *ptr, std::align_val_t align) NOEXCEPT { 12554263Sshin OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR); 12654263Sshin} 12754263SshinCXX_OPERATOR_ATTRIBUTE 12854263Sshinvoid operator delete(void *ptr, std::align_val_t align, 12954263Sshin std::nothrow_t const &) { 13054263Sshin OPERATOR_DELETE_BODY_ALIGN(FROM_NEW); 13154263Sshin} 13254263SshinCXX_OPERATOR_ATTRIBUTE 13354263Sshinvoid operator delete[](void *ptr, std::align_val_t align, 13454263Sshin std::nothrow_t const &) { 13554263Sshin OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR); 13654263Sshin} 13754263SshinCXX_OPERATOR_ATTRIBUTE 13854263Sshinvoid operator delete(void *ptr, size_t size, std::align_val_t align)NOEXCEPT { 13954263Sshin OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW); 14054263Sshin} 14154263SshinCXX_OPERATOR_ATTRIBUTE 14254263Sshinvoid operator delete[](void *ptr, size_t size, 14354263Sshin std::align_val_t align) NOEXCEPT { 14454263Sshin OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW_BR); 14554263Sshin} 14654263Sshin