1cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar//===-- tsan_new_delete.cc ----------------------------------------------===//
2cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar//
3cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar//                     The LLVM Compiler Infrastructure
4cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar//
5cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source
6cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar// License. See LICENSE.TXT for details.
7cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar//
8cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar//===----------------------------------------------------------------------===//
9cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar//
10cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar// This file is a part of ThreadSanitizer (TSan), a race detector.
11cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar//
12cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar// Interceptors for operators new and delete.
13cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar//===----------------------------------------------------------------------===//
143d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#include "interception/interception.h"
15cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#include "sanitizer_common/sanitizer_internal_defs.h"
16cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#include "tsan_interceptors.h"
17cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
18cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarusing namespace __tsan;  // NOLINT
19cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
20cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarnamespace std {
21cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarstruct nothrow_t {};
22cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}  // namespace std
23cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
243d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga NainarDECLARE_REAL(void *, malloc, uptr size)
253d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga NainarDECLARE_REAL(void, free, void *ptr)
263d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#if SANITIZER_MAC || SANITIZER_ANDROID
273d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define __libc_malloc REAL(malloc)
283d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define __libc_free REAL(free)
293d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#endif
303d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
31cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define OPERATOR_NEW_BODY(mangled_name) \
32cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  if (cur_thread()->in_symbolizer) \
33cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    return __libc_malloc(size); \
34cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  void *p = 0; \
35cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  {  \
36cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
37cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    p = user_alloc(thr, pc, size); \
38cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  }  \
39cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  invoke_malloc_hook(p, size);  \
40cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  return p;
41cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
42cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarSANITIZER_INTERFACE_ATTRIBUTE
43cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarvoid *operator new(__sanitizer::uptr size);
44cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarvoid *operator new(__sanitizer::uptr size) {
45cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  OPERATOR_NEW_BODY(_Znwm);
46cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
47cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
48cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarSANITIZER_INTERFACE_ATTRIBUTE
49cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarvoid *operator new[](__sanitizer::uptr size);
50cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarvoid *operator new[](__sanitizer::uptr size) {
51cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  OPERATOR_NEW_BODY(_Znam);
52cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
53cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
54cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarSANITIZER_INTERFACE_ATTRIBUTE
55cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarvoid *operator new(__sanitizer::uptr size, std::nothrow_t const&);
56cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarvoid *operator new(__sanitizer::uptr size, std::nothrow_t const&) {
57cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t);
58cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
59cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
60cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarSANITIZER_INTERFACE_ATTRIBUTE
61cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarvoid *operator new[](__sanitizer::uptr size, std::nothrow_t const&);
62cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarvoid *operator new[](__sanitizer::uptr size, std::nothrow_t const&) {
63cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t);
64cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
65cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
66cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar#define OPERATOR_DELETE_BODY(mangled_name) \
67cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  if (ptr == 0) return;  \
68cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  if (cur_thread()->in_symbolizer) \
69cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar    return __libc_free(ptr); \
70cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  invoke_free_hook(ptr);  \
71cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  SCOPED_INTERCEPTOR_RAW(mangled_name, ptr);  \
72cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  user_free(thr, pc, ptr);
73cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
74cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarSANITIZER_INTERFACE_ATTRIBUTE
753d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarvoid operator delete(void *ptr) NOEXCEPT;
763d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarvoid operator delete(void *ptr) NOEXCEPT {
77cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  OPERATOR_DELETE_BODY(_ZdlPv);
78cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
79cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
80cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarSANITIZER_INTERFACE_ATTRIBUTE
813d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarvoid operator delete[](void *ptr) NOEXCEPT;
823d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarvoid operator delete[](void *ptr) NOEXCEPT {
83cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  OPERATOR_DELETE_BODY(_ZdaPv);
84cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
85cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
86cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarSANITIZER_INTERFACE_ATTRIBUTE
87cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarvoid operator delete(void *ptr, std::nothrow_t const&);
88cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarvoid operator delete(void *ptr, std::nothrow_t const&) {
89cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t);
90cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
91cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
92cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga NainarSANITIZER_INTERFACE_ATTRIBUTE
93cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarvoid operator delete[](void *ptr, std::nothrow_t const&);
94cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainarvoid operator delete[](void *ptr, std::nothrow_t const&) {
95cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar  OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t);
96cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar}
97