blob: 3327e08f7dcb1d68bebb07dbde5af0356741bf9b [file] [log] [blame]
kwibergac554ee2016-09-02 00:39:33 -07001/*
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef WEBRTC_BASE_SANITIZER_H_
12#define WEBRTC_BASE_SANITIZER_H_
13
14#if defined(__has_feature)
15#if __has_feature(address_sanitizer)
16#define RTC_HAS_ASAN 1
17#endif
18#if __has_feature(memory_sanitizer)
19#define RTC_HAS_MSAN 1
20#endif
21#endif
22#ifndef RTC_HAS_ASAN
23#define RTC_HAS_ASAN 0
24#endif
25#ifndef RTC_HAS_MSAN
26#define RTC_HAS_MSAN 0
27#endif
28
29#if RTC_HAS_ASAN
30#include <sanitizer/asan_interface.h>
31#endif
32#if RTC_HAS_MSAN
33#include <sanitizer/msan_interface.h>
34#endif
35
36// Ask ASan to mark the memory range [ptr, ptr + element_size * num_elements)
37// as being unaddressable, so that reads and writes are not allowed. ASan may
38// narrow the range to the nearest alignment boundaries.
39static inline void rtc_AsanPoison(const volatile void* ptr,
40 size_t element_size,
41 size_t num_elements) {
42#if RTC_HAS_ASAN
43 ASAN_POISON_MEMORY_REGION(ptr, element_size * num_elements);
44#endif
45}
46
47// Ask ASan to mark the memory range [ptr, ptr + element_size * num_elements)
48// as being addressable, so that reads and writes are allowed. ASan may widen
49// the range to the nearest alignment boundaries.
50static inline void rtc_AsanUnpoison(const volatile void* ptr,
51 size_t element_size,
52 size_t num_elements) {
53#if RTC_HAS_ASAN
54 ASAN_UNPOISON_MEMORY_REGION(ptr, element_size * num_elements);
55#endif
56}
57
58// Ask MSan to mark the memory range [ptr, ptr + element_size * num_elements)
59// as being uninitialized.
60static inline void rtc_MsanMarkUninitialized(const volatile void* ptr,
61 size_t element_size,
62 size_t num_elements) {
63#if RTC_HAS_MSAN
64 __msan_poison(ptr, element_size * num_elements);
65#endif
66}
67
68// Force an MSan check (if any bits in the memory range [ptr, ptr +
69// element_size * num_elements) are uninitialized the call will crash with an
70// MSan report).
71static inline void rtc_MsanCheckInitialized(const volatile void* ptr,
72 size_t element_size,
73 size_t num_elements) {
74#if RTC_HAS_MSAN
75 __msan_check_mem_is_initialized(ptr, element_size * num_elements);
76#endif
77}
78
79#ifdef __cplusplus
80
81namespace rtc {
82
83template <typename T>
84inline void AsanPoison(const T& mem) {
85 rtc_AsanPoison(mem.data(), sizeof(mem.data()[0]), mem.size());
86}
87
88template <typename T>
89inline void AsanUnpoison(const T& mem) {
90 rtc_AsanUnpoison(mem.data(), sizeof(mem.data()[0]), mem.size());
91}
92
93template <typename T>
94inline void MsanMarkUninitialized(const T& mem) {
95 rtc_MsanMarkUninitialized(mem.data(), sizeof(mem.data()[0]), mem.size());
96}
97
98template <typename T>
99inline void MsanCheckInitialized(const T& mem) {
100 rtc_MsanCheckInitialized(mem.data(), sizeof(mem.data()[0]), mem.size());
101}
102
103} // namespace rtc
104
105#endif // __cplusplus
106
107#endif // WEBRTC_BASE_SANITIZER_H_