1 1.1 kamil //===-- ubsan_value.h -------------------------------------------*- C++ -*-===// 2 1.1 kamil // 3 1.1 kamil // The LLVM Compiler Infrastructure 4 1.1 kamil // 5 1.1 kamil // This file is distributed under the University of Illinois Open Source 6 1.1 kamil // License. See LICENSE.TXT for details. 7 1.1 kamil // 8 1.1 kamil //===----------------------------------------------------------------------===// 9 1.1 kamil // 10 1.1 kamil // Representation of data which is passed from the compiler-generated calls into 11 1.1 kamil // the ubsan runtime. 12 1.1 kamil // 13 1.1 kamil //===----------------------------------------------------------------------===// 14 1.1 kamil #ifndef UBSAN_VALUE_H 15 1.1 kamil #define UBSAN_VALUE_H 16 1.1 kamil 17 1.1 kamil #include "sanitizer_common/sanitizer_atomic.h" 18 1.1 kamil #include "sanitizer_common/sanitizer_common.h" 19 1.1 kamil 20 1.1 kamil // FIXME: Move this out to a config header. 21 1.1 kamil #if __SIZEOF_INT128__ 22 1.1 kamil __extension__ typedef __int128 s128; 23 1.1 kamil __extension__ typedef unsigned __int128 u128; 24 1.1 kamil #define HAVE_INT128_T 1 25 1.1 kamil #else 26 1.1 kamil #define HAVE_INT128_T 0 27 1.1 kamil #endif 28 1.1 kamil 29 1.1 kamil namespace __ubsan { 30 1.1 kamil 31 1.1 kamil /// \brief Largest integer types we support. 32 1.1 kamil #if HAVE_INT128_T 33 1.1 kamil typedef s128 SIntMax; 34 1.1 kamil typedef u128 UIntMax; 35 1.1 kamil #else 36 1.1 kamil typedef s64 SIntMax; 37 1.1 kamil typedef u64 UIntMax; 38 1.1 kamil #endif 39 1.1 kamil 40 1.1 kamil /// \brief Largest floating-point type we support. 41 1.1 kamil typedef long double FloatMax; 42 1.1 kamil 43 1.1 kamil /// \brief A description of a source location. This corresponds to Clang's 44 1.1 kamil /// \c PresumedLoc type. 45 1.1 kamil class SourceLocation { 46 1.1 kamil const char *Filename; 47 1.1 kamil u32 Line; 48 1.1 kamil u32 Column; 49 1.1 kamil 50 1.1 kamil public: 51 1.1 kamil SourceLocation() : Filename(), Line(), Column() {} 52 1.1 kamil SourceLocation(const char *Filename, unsigned Line, unsigned Column) 53 1.1 kamil : Filename(Filename), Line(Line), Column(Column) {} 54 1.1 kamil 55 1.1 kamil /// \brief Determine whether the source location is known. 56 1.1 kamil bool isInvalid() const { return !Filename; } 57 1.1 kamil 58 1.1 kamil /// \brief Atomically acquire a copy, disabling original in-place. 59 1.1 kamil /// Exactly one call to acquire() returns a copy that isn't disabled. 60 1.1 kamil SourceLocation acquire() { 61 1.1 kamil u32 OldColumn = __sanitizer::atomic_exchange( 62 1.1 kamil (__sanitizer::atomic_uint32_t *)&Column, ~u32(0), 63 1.1 kamil __sanitizer::memory_order_relaxed); 64 1.1 kamil return SourceLocation(Filename, Line, OldColumn); 65 1.1 kamil } 66 1.1 kamil 67 1.1 kamil /// \brief Determine if this Location has been disabled. 68 1.1 kamil /// Disabled SourceLocations are invalid to use. 69 1.1 kamil bool isDisabled() { 70 1.1 kamil return Column == ~u32(0); 71 1.1 kamil } 72 1.1 kamil 73 1.1 kamil /// \brief Get the presumed filename for the source location. 74 1.1 kamil const char *getFilename() const { return Filename; } 75 1.1 kamil /// \brief Get the presumed line number. 76 1.1 kamil unsigned getLine() const { return Line; } 77 1.1 kamil /// \brief Get the column within the presumed line. 78 1.1 kamil unsigned getColumn() const { return Column; } 79 1.1 kamil }; 80 1.1 kamil 81 1.1 kamil 82 1.1 kamil /// \brief A description of a type. 83 1.1 kamil class TypeDescriptor { 84 1.1 kamil /// A value from the \c Kind enumeration, specifying what flavor of type we 85 1.1 kamil /// have. 86 1.1 kamil u16 TypeKind; 87 1.1 kamil 88 1.1 kamil /// A \c Type-specific value providing information which allows us to 89 1.1 kamil /// interpret the meaning of a ValueHandle of this type. 90 1.1 kamil u16 TypeInfo; 91 1.1 kamil 92 1.1 kamil /// The name of the type follows, in a format suitable for including in 93 1.1 kamil /// diagnostics. 94 1.1 kamil char TypeName[1]; 95 1.1 kamil 96 1.1 kamil public: 97 1.1 kamil enum Kind { 98 1.1 kamil /// An integer type. Lowest bit is 1 for a signed value, 0 for an unsigned 99 1.1 kamil /// value. Remaining bits are log_2(bit width). The value representation is 100 1.1 kamil /// the integer itself if it fits into a ValueHandle, and a pointer to the 101 1.1 kamil /// integer otherwise. 102 1.1 kamil TK_Integer = 0x0000, 103 1.1 kamil /// A floating-point type. Low 16 bits are bit width. The value 104 1.1 kamil /// representation is that of bitcasting the floating-point value to an 105 1.1 kamil /// integer type. 106 1.1 kamil TK_Float = 0x0001, 107 1.1 kamil /// Any other type. The value representation is unspecified. 108 1.1 kamil TK_Unknown = 0xffff 109 1.1 kamil }; 110 1.1 kamil 111 1.1 kamil const char *getTypeName() const { return TypeName; } 112 1.1 kamil 113 1.1 kamil Kind getKind() const { 114 1.1 kamil return static_cast<Kind>(TypeKind); 115 1.1 kamil } 116 1.1 kamil 117 1.1 kamil bool isIntegerTy() const { return getKind() == TK_Integer; } 118 1.1 kamil bool isSignedIntegerTy() const { 119 1.1 kamil return isIntegerTy() && (TypeInfo & 1); 120 1.1 kamil } 121 1.1 kamil bool isUnsignedIntegerTy() const { 122 1.1 kamil return isIntegerTy() && !(TypeInfo & 1); 123 1.1 kamil } 124 1.1 kamil unsigned getIntegerBitWidth() const { 125 1.1 kamil CHECK(isIntegerTy()); 126 1.1 kamil return 1 << (TypeInfo >> 1); 127 1.1 kamil } 128 1.1 kamil 129 1.1 kamil bool isFloatTy() const { return getKind() == TK_Float; } 130 1.1 kamil unsigned getFloatBitWidth() const { 131 1.1 kamil CHECK(isFloatTy()); 132 1.1 kamil return TypeInfo; 133 1.1 kamil } 134 1.1 kamil }; 135 1.1 kamil 136 1.1 kamil /// \brief An opaque handle to a value. 137 1.1 kamil typedef uptr ValueHandle; 138 1.1 kamil 139 1.1 kamil 140 1.1 kamil /// \brief Representation of an operand value provided by the instrumented code. 141 1.1 kamil /// 142 1.1 kamil /// This is a combination of a TypeDescriptor (which is emitted as constant data 143 1.1 kamil /// as an operand to a handler function) and a ValueHandle (which is passed at 144 1.1 kamil /// runtime when a check failure occurs). 145 1.1 kamil class Value { 146 1.1 kamil /// The type of the value. 147 1.1 kamil const TypeDescriptor &Type; 148 1.1 kamil /// The encoded value itself. 149 1.1 kamil ValueHandle Val; 150 1.1 kamil 151 1.1 kamil /// Is \c Val a (zero-extended) integer? 152 1.1 kamil bool isInlineInt() const { 153 1.1 kamil CHECK(getType().isIntegerTy()); 154 1.1 kamil const unsigned InlineBits = sizeof(ValueHandle) * 8; 155 1.1 kamil const unsigned Bits = getType().getIntegerBitWidth(); 156 1.1 kamil return Bits <= InlineBits; 157 1.1 kamil } 158 1.1 kamil 159 1.1 kamil /// Is \c Val a (zero-extended) integer representation of a float? 160 1.1 kamil bool isInlineFloat() const { 161 1.1 kamil CHECK(getType().isFloatTy()); 162 1.1 kamil const unsigned InlineBits = sizeof(ValueHandle) * 8; 163 1.1 kamil const unsigned Bits = getType().getFloatBitWidth(); 164 1.1 kamil return Bits <= InlineBits; 165 1.1 kamil } 166 1.1 kamil 167 1.1 kamil public: 168 1.1 kamil Value(const TypeDescriptor &Type, ValueHandle Val) : Type(Type), Val(Val) {} 169 1.1 kamil 170 1.1 kamil const TypeDescriptor &getType() const { return Type; } 171 1.1 kamil 172 1.1 kamil /// \brief Get this value as a signed integer. 173 1.1 kamil SIntMax getSIntValue() const; 174 1.1 kamil 175 1.1 kamil /// \brief Get this value as an unsigned integer. 176 1.1 kamil UIntMax getUIntValue() const; 177 1.1 kamil 178 1.1 kamil /// \brief Decode this value, which must be a positive or unsigned integer. 179 1.1 kamil UIntMax getPositiveIntValue() const; 180 1.1 kamil 181 1.1 kamil /// Is this an integer with value -1? 182 1.1 kamil bool isMinusOne() const { 183 1.1 kamil return getType().isSignedIntegerTy() && getSIntValue() == -1; 184 1.1 kamil } 185 1.1 kamil 186 1.1 kamil /// Is this a negative integer? 187 1.1 kamil bool isNegative() const { 188 1.1 kamil return getType().isSignedIntegerTy() && getSIntValue() < 0; 189 1.1 kamil } 190 1.1 kamil 191 1.1 kamil /// \brief Get this value as a floating-point quantity. 192 1.1 kamil FloatMax getFloatValue() const; 193 1.1 kamil }; 194 1.1 kamil 195 1.1 kamil } // namespace __ubsan 196 1.1 kamil 197 1.1 kamil #endif // UBSAN_VALUE_H 198