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 15 namespace scudo { 16 17 enum class OptionBit { 18 MayReturnNull, 19 FillContents0of2, 20 FillContents1of2, 21 DeallocTypeMismatch, 22 DeleteSizeMismatch, 23 TrackAllocationStacks, 24 UseOddEvenTags, 25 UseMemoryTagging, 26 }; 27 28 struct Options { 29 u32 Val; 30 getOptions31 bool get(OptionBit Opt) const { return Val & (1U << static_cast<u32>(Opt)); } 32 getFillContentsModeOptions33 FillContentsMode getFillContentsMode() const { 34 return static_cast<FillContentsMode>( 35 (Val >> static_cast<u32>(OptionBit::FillContents0of2)) & 3); 36 } 37 }; 38 39 struct AtomicOptions { 40 atomic_u32 Val; 41 42 public: loadAtomicOptions43 Options load() const { return Options{atomic_load_relaxed(&Val)}; } 44 clearAtomicOptions45 void clear(OptionBit Opt) { 46 atomic_fetch_and(&Val, ~(1U << static_cast<u32>(Opt)), 47 memory_order_relaxed); 48 } 49 setAtomicOptions50 void set(OptionBit Opt) { 51 atomic_fetch_or(&Val, 1U << static_cast<u32>(Opt), memory_order_relaxed); 52 } 53 setFillContentsModeAtomicOptions54 void setFillContentsMode(FillContentsMode FillContents) { 55 u32 Opts = atomic_load_relaxed(&Val), NewOpts; 56 do { 57 NewOpts = Opts; 58 NewOpts &= ~(3U << static_cast<u32>(OptionBit::FillContents0of2)); 59 NewOpts |= static_cast<u32>(FillContents) 60 << static_cast<u32>(OptionBit::FillContents0of2); 61 } while (!atomic_compare_exchange_strong(&Val, &Opts, NewOpts, 62 memory_order_relaxed)); 63 } 64 }; 65 66 } // namespace scudo 67 68 #endif // SCUDO_OPTIONS_H_ 69