1 | //===-- options.h -----------------------------------------------*- 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 | #ifndef SCUDO_OPTIONS_H_ |
10 | #define SCUDO_OPTIONS_H_ |
11 | |
12 | #include "atomic_helpers.h" |
13 | #include "common.h" |
14 | #include "memtag.h" |
15 | |
16 | namespace scudo { |
17 | |
18 | enum class OptionBit { |
19 | MayReturnNull, |
20 | FillContents0of2, |
21 | FillContents1of2, |
22 | DeallocTypeMismatch, |
23 | DeleteSizeMismatch, |
24 | TrackAllocationStacks, |
25 | UseOddEvenTags, |
26 | UseMemoryTagging, |
27 | AddLargeAllocationSlack, |
28 | }; |
29 | |
30 | struct Options { |
31 | u32 Val; |
32 | |
33 | bool get(OptionBit Opt) const { return Val & (1U << static_cast<u32>(Opt)); } |
34 | |
35 | FillContentsMode getFillContentsMode() const { |
36 | return static_cast<FillContentsMode>( |
37 | (Val >> static_cast<u32>(OptionBit::FillContents0of2)) & 3); |
38 | } |
39 | }; |
40 | |
41 | template <typename Config> bool useMemoryTagging(const Options &Options) { |
42 | return allocatorSupportsMemoryTagging<Config>() && |
43 | Options.get(Opt: OptionBit::UseMemoryTagging); |
44 | } |
45 | |
46 | struct AtomicOptions { |
47 | atomic_u32 Val = {}; |
48 | |
49 | Options load() const { return Options{.Val: atomic_load_relaxed(A: &Val)}; } |
50 | |
51 | void clear(OptionBit Opt) { |
52 | atomic_fetch_and(A: &Val, V: ~(1U << static_cast<u32>(Opt)), |
53 | MO: memory_order_relaxed); |
54 | } |
55 | |
56 | void set(OptionBit Opt) { |
57 | atomic_fetch_or(A: &Val, V: 1U << static_cast<u32>(Opt), MO: memory_order_relaxed); |
58 | } |
59 | |
60 | void setFillContentsMode(FillContentsMode FillContents) { |
61 | u32 Opts = atomic_load_relaxed(A: &Val), NewOpts; |
62 | do { |
63 | NewOpts = Opts; |
64 | NewOpts &= ~(3U << static_cast<u32>(OptionBit::FillContents0of2)); |
65 | NewOpts |= static_cast<u32>(FillContents) |
66 | << static_cast<u32>(OptionBit::FillContents0of2); |
67 | } while (!atomic_compare_exchange_strong(A: &Val, Cmp: &Opts, Xchg: NewOpts, |
68 | MO: memory_order_relaxed)); |
69 | } |
70 | }; |
71 | |
72 | } // namespace scudo |
73 | |
74 | #endif // SCUDO_OPTIONS_H_ |
75 | |