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