xref: /openbsd-src/gnu/llvm/compiler-rt/lib/scudo/standalone/options.h (revision d89ec533011f513df1010f142a111086a0785f09)
1*d89ec533Spatrick //===-- options.h -----------------------------------------------*- C++ -*-===//
2*d89ec533Spatrick //
3*d89ec533Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*d89ec533Spatrick // See https://llvm.org/LICENSE.txt for license information.
5*d89ec533Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*d89ec533Spatrick //
7*d89ec533Spatrick //===----------------------------------------------------------------------===//
8*d89ec533Spatrick 
9*d89ec533Spatrick #ifndef SCUDO_OPTIONS_H_
10*d89ec533Spatrick #define SCUDO_OPTIONS_H_
11*d89ec533Spatrick 
12*d89ec533Spatrick #include "atomic_helpers.h"
13*d89ec533Spatrick #include "common.h"
14*d89ec533Spatrick #include "memtag.h"
15*d89ec533Spatrick 
16*d89ec533Spatrick namespace scudo {
17*d89ec533Spatrick 
18*d89ec533Spatrick enum class OptionBit {
19*d89ec533Spatrick   MayReturnNull,
20*d89ec533Spatrick   FillContents0of2,
21*d89ec533Spatrick   FillContents1of2,
22*d89ec533Spatrick   DeallocTypeMismatch,
23*d89ec533Spatrick   DeleteSizeMismatch,
24*d89ec533Spatrick   TrackAllocationStacks,
25*d89ec533Spatrick   UseOddEvenTags,
26*d89ec533Spatrick   UseMemoryTagging,
27*d89ec533Spatrick   AddLargeAllocationSlack,
28*d89ec533Spatrick };
29*d89ec533Spatrick 
30*d89ec533Spatrick struct Options {
31*d89ec533Spatrick   u32 Val;
32*d89ec533Spatrick 
getOptions33*d89ec533Spatrick   bool get(OptionBit Opt) const { return Val & (1U << static_cast<u32>(Opt)); }
34*d89ec533Spatrick 
getFillContentsModeOptions35*d89ec533Spatrick   FillContentsMode getFillContentsMode() const {
36*d89ec533Spatrick     return static_cast<FillContentsMode>(
37*d89ec533Spatrick         (Val >> static_cast<u32>(OptionBit::FillContents0of2)) & 3);
38*d89ec533Spatrick   }
39*d89ec533Spatrick };
40*d89ec533Spatrick 
useMemoryTagging(Options Options)41*d89ec533Spatrick template <typename Config> bool useMemoryTagging(Options Options) {
42*d89ec533Spatrick   return allocatorSupportsMemoryTagging<Config>() &&
43*d89ec533Spatrick          Options.get(OptionBit::UseMemoryTagging);
44*d89ec533Spatrick }
45*d89ec533Spatrick 
46*d89ec533Spatrick struct AtomicOptions {
47*d89ec533Spatrick   atomic_u32 Val = {};
48*d89ec533Spatrick 
loadAtomicOptions49*d89ec533Spatrick   Options load() const { return Options{atomic_load_relaxed(&Val)}; }
50*d89ec533Spatrick 
clearAtomicOptions51*d89ec533Spatrick   void clear(OptionBit Opt) {
52*d89ec533Spatrick     atomic_fetch_and(&Val, ~(1U << static_cast<u32>(Opt)),
53*d89ec533Spatrick                      memory_order_relaxed);
54*d89ec533Spatrick   }
55*d89ec533Spatrick 
setAtomicOptions56*d89ec533Spatrick   void set(OptionBit Opt) {
57*d89ec533Spatrick     atomic_fetch_or(&Val, 1U << static_cast<u32>(Opt), memory_order_relaxed);
58*d89ec533Spatrick   }
59*d89ec533Spatrick 
setFillContentsModeAtomicOptions60*d89ec533Spatrick   void setFillContentsMode(FillContentsMode FillContents) {
61*d89ec533Spatrick     u32 Opts = atomic_load_relaxed(&Val), NewOpts;
62*d89ec533Spatrick     do {
63*d89ec533Spatrick       NewOpts = Opts;
64*d89ec533Spatrick       NewOpts &= ~(3U << static_cast<u32>(OptionBit::FillContents0of2));
65*d89ec533Spatrick       NewOpts |= static_cast<u32>(FillContents)
66*d89ec533Spatrick                  << static_cast<u32>(OptionBit::FillContents0of2);
67*d89ec533Spatrick     } while (!atomic_compare_exchange_strong(&Val, &Opts, NewOpts,
68*d89ec533Spatrick                                              memory_order_relaxed));
69*d89ec533Spatrick   }
70*d89ec533Spatrick };
71*d89ec533Spatrick 
72*d89ec533Spatrick } // namespace scudo
73*d89ec533Spatrick 
74*d89ec533Spatrick #endif // SCUDO_OPTIONS_H_
75