1e5f5895bda30f374b0b51412fd4d837fa59aed66Alexey Samsonov//===-- asan_interceptors.cc ----------------------------------------------===//
24d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov//
34d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov//                     The LLVM Compiler Infrastructure
44d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov//
54d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// This file is distributed under the University of Illinois Open Source
64d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// License. See LICENSE.TXT for details.
74d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov//
84d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov//===----------------------------------------------------------------------===//
94d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov//
104d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// This file is a part of AddressSanitizer, an address sanity checker.
114d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov//
124d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// Interceptors for operators new and delete.
134d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov//===----------------------------------------------------------------------===//
144d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov
154d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov#include "asan_allocator.h"
164d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov#include "asan_internal.h"
174d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov#include "asan_stack.h"
184d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov
192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_common/sanitizer_interception.h"
202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
21cfd605e96209d18c937501be870bd0308131e453Kostya Serebryany#include <stddef.h>
224d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov
232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// C++ operators can't have visibility attributes on Windows.
242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_WINDOWS
252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# define CXX_OPERATOR_ATTRIBUTE
262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else
272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE
282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
294d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov
304d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonovusing namespace __asan;  // NOLINT
314d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov
322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This code has issues on OSX.
332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// See https://code.google.com/p/address-sanitizer/issues/detail?id=131.
34dbe60352ef7240327f15f813140c9726854f6b85Evgeniy Stepanov
353aa15c1ad60ae6c63973a0982662f26449f661bcAlexey Samsonov// Fake std::nothrow_t to avoid including <new>.
363aa15c1ad60ae6c63973a0982662f26449f661bcAlexey Samsonovnamespace std {
373aa15c1ad60ae6c63973a0982662f26449f661bcAlexey Samsonovstruct nothrow_t {};
383aa15c1ad60ae6c63973a0982662f26449f661bcAlexey Samsonov}  // namespace std
393aa15c1ad60ae6c63973a0982662f26449f661bcAlexey Samsonov
40fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany#define OPERATOR_NEW_BODY(type) \
41a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany  GET_STACK_TRACE_MALLOC;\
42fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany  return asan_memalign(0, size, &stack, type);
434d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov
44d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// On OS X it's not enough to just provide our own 'operator new' and
45d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// 'operator delete' implementations, because they're going to be in the
46d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// runtime dylib, and the main executable will depend on both the runtime
47d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// dylib and libstdc++, each of those'll have its implementation of new and
48d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// delete.
49d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// To make sure that C++ allocation/deallocation operators are overridden on
50d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// OS X we need to intercept them using their mangled names.
5124e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#if !SANITIZER_MAC
522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FreeBSD prior v9.2 have wrong definition of 'size_t'.
532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// http://svnweb.freebsd.org/base?view=revision&revision=232261
542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32
552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <sys/param.h>
562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if __FreeBSD_version <= 902001  // v9.2
572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define size_t unsigned
582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // __FreeBSD_version
592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif  // SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32
602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines
612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE
62fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryanyvoid *operator new(size_t size) { OPERATOR_NEW_BODY(FROM_NEW); }
632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE
64fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryanyvoid *operator new[](size_t size) { OPERATOR_NEW_BODY(FROM_NEW_BR); }
652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE
66fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryanyvoid *operator new(size_t size, std::nothrow_t const&)
67fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany{ OPERATOR_NEW_BODY(FROM_NEW); }
682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE
69fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryanyvoid *operator new[](size_t size, std::nothrow_t const&)
70fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany{ OPERATOR_NEW_BODY(FROM_NEW_BR); }
714d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov
72649a270f5341efe9c57f473dbb78706b0b2ed523Alexey Samsonov#else  // SANITIZER_MAC
73d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void *, _Znwm, size_t size) {
74d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko  OPERATOR_NEW_BODY(FROM_NEW);
75d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko}
76d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void *, _Znam, size_t size) {
77d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko  OPERATOR_NEW_BODY(FROM_NEW_BR);
78d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko}
79d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) {
80d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko  OPERATOR_NEW_BODY(FROM_NEW);
81d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko}
82d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) {
83d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko  OPERATOR_NEW_BODY(FROM_NEW_BR);
84d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko}
85d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko#endif
86d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko
87fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany#define OPERATOR_DELETE_BODY(type) \
88a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany  GET_STACK_TRACE_FREE;\
89fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany  asan_free(ptr, &stack, type);
904d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov
9124e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#if !SANITIZER_MAC
922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE
932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid operator delete(void *ptr) throw() {
942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  OPERATOR_DELETE_BODY(FROM_NEW);
952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE
972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid operator delete[](void *ptr) throw() {
982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  OPERATOR_DELETE_BODY(FROM_NEW_BR);
992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE
1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid operator delete(void *ptr, std::nothrow_t const&) {
1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  OPERATOR_DELETE_BODY(FROM_NEW);
1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE
1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid operator delete[](void *ptr, std::nothrow_t const&) {
1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines  OPERATOR_DELETE_BODY(FROM_NEW_BR);
1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
108dbe60352ef7240327f15f813140c9726854f6b85Evgeniy Stepanov
109649a270f5341efe9c57f473dbb78706b0b2ed523Alexey Samsonov#else  // SANITIZER_MAC
110d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void, _ZdlPv, void *ptr) {
111d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko  OPERATOR_DELETE_BODY(FROM_NEW);
112d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko}
113d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void, _ZdaPv, void *ptr) {
114d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko  OPERATOR_DELETE_BODY(FROM_NEW_BR);
115d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko}
116d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) {
117d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko  OPERATOR_DELETE_BODY(FROM_NEW);
118d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko}
119d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) {
120d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko  OPERATOR_DELETE_BODY(FROM_NEW_BR);
121d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko}
122d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko#endif
123