scudo_new_delete.cpp 4.1 KB

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